Hello community, here is the log from the commit of package python-httpretty for openSUSE:Factory checked in at 2014-04-03 17:14:28 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-httpretty (Old) and /work/SRC/openSUSE:Factory/.python-httpretty.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-httpretty" Changes: -------- --- /work/SRC/openSUSE:Factory/python-httpretty/python-httpretty.changes 2014-01-23 15:54:12.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.python-httpretty.new/python-httpretty.changes 2014-04-03 17:14:29.000000000 +0200 @@ -1,0 +2,12 @@ +Mon Feb 17 12:50:39 UTC 2014 - [email protected] + +- Drop old tarball + +------------------------------------------------------------------- +Mon Feb 17 10:02:32 UTC 2014 - [email protected] + +- update to 0.8.0: + * This new version brings Python 3 support, leaner requirements +- remove deps-cleanup.diff + +------------------------------------------------------------------- Old: ---- deps-cleanup.diff httpretty-0.7.1.tar.gz New: ---- httpretty-0.8.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-httpretty.spec ++++++ --- /var/tmp/diff_new_pack.OUP5wn/_old 2014-04-03 17:14:29.000000000 +0200 +++ /var/tmp/diff_new_pack.OUP5wn/_new 2014-04-03 17:14:29.000000000 +0200 @@ -17,17 +17,21 @@ Name: python-httpretty -Version: 0.7.1 +Version: 0.8.0 Release: 0 Summary: HTTP client mock for Python License: MIT Group: Development/Languages/Python Url: http://github.com/gabrielfalcao/httpretty Source: https://pypi.python.org/packages/source/h/httpretty/httpretty-%{version}.tar.gz -# PATCH-FIX-OPENSUSE [email protected] -- Don't require fixed versions -Patch0: deps-cleanup.diff BuildRequires: python-devel BuildRequires: python-setuptools +# Test requirements +#BuildRequires: python-httplib2 +#BuildRequires: python-requests +#BuildRequires: python-sure +BuildRequires: python-urllib3 +Requires: python-urllib3 BuildRoot: %{_tmppath}/%{name}-%{version}-build %if 0%{?suse_version} && 0%{?suse_version} <= 1110 %{!?python_sitelib: %global python_sitelib %(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} @@ -41,14 +45,18 @@ %prep %setup -q -n httpretty-%{version} -%patch0 -p1 %build python setup.py build %install python setup.py install --prefix=%{_prefix} --root=%{buildroot} -rm -r %{buildroot}%{python_sitelib}/tests # Remove global "tests" module + +# crazy deps still +%if 0 +%check +python setup.py test +%endif %files %defattr(-,root,root,-) ++++++ httpretty-0.7.1.tar.gz -> httpretty-0.8.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpretty-0.7.1/COPYING new/httpretty-0.8.0/COPYING --- old/httpretty-0.7.1/COPYING 1970-01-01 01:00:00.000000000 +0100 +++ new/httpretty-0.8.0/COPYING 2014-02-03 18:24:56.000000000 +0100 @@ -0,0 +1,22 @@ +Copyright (C) <2011-2013> Gabriel Falcão <[email protected]> + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpretty-0.7.1/MANIFEST.in new/httpretty-0.8.0/MANIFEST.in --- old/httpretty-0.7.1/MANIFEST.in 2013-12-12 17:44:50.000000000 +0100 +++ new/httpretty-0.8.0/MANIFEST.in 2014-02-03 18:24:56.000000000 +0100 @@ -1,2 +1,9 @@ include requirements.txt - +include test-requirements.txt +include dev-requirements.txt +recursive-include tests *.py +include tests/functional/fixtures/playback-*.json +include COPYING +include Makefile +include README.md +include tox.ini diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpretty-0.7.1/Makefile new/httpretty-0.8.0/Makefile --- old/httpretty-0.7.1/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ new/httpretty-0.8.0/Makefile 2014-02-03 18:24:56.000000000 +0100 @@ -0,0 +1,52 @@ +all: check_dependencies unit functional doctests + +filename=httpretty-`python -c 'import httpretty;print httpretty.version'`.tar.gz + +export HTTPRETTY_DEPENDENCIES:= nose sure +export PYTHONPATH:= ${PWD} + +check_dependencies: + @echo "Checking for dependencies to run tests ..." + @for dependency in `echo $$HTTPRETTY_DEPENDENCIES`; do \ + python -c "import $$dependency" 2>/dev/null || (echo "You must install $$dependency in order to run httpretty's tests" && exit 3) ; \ + done + +test: unit functional doctests + +unit: prepare + @echo "Running unit tests ..." + @nosetests -s tests/unit + +functional: prepare + @echo "Running functional tests ..." + @nosetests -s tests/functional + +doctests: prepare + @echo "Running documentation tests tests ..." + @steadymark README.md + +clean: + @printf "Cleaning up files that are already in .gitignore... " + @for pattern in `cat .gitignore`; do rm -rf $$pattern; done + @echo "OK!" + +release: clean unit functional + @echo "Releasing httpretty..." + @./.release + @python setup.py sdist register upload + +docs: doctests + @markment -o . -t ./theme --sitemap-for="http://falcao.it/HTTPretty" docs + +deploy-docs: + @git co master && \ + (git br -D gh-pages || printf "") && \ + git checkout --orphan gh-pages && \ + markment -o . -t ./theme --sitemap-for="http://falcao.it/HTTPretty" docs && \ + git add . && \ + git commit -am 'documentation' && \ + git push --force origin gh-pages && \ + git checkout master + +prepare: + @reset diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpretty-0.7.1/PKG-INFO new/httpretty-0.8.0/PKG-INFO --- old/httpretty-0.7.1/PKG-INFO 2013-12-12 18:25:48.000000000 +0100 +++ new/httpretty-0.8.0/PKG-INFO 2014-02-03 20:17:12.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: httpretty -Version: 0.7.1 +Version: 0.8.0 Summary: HTTP client mock for Python Home-page: http://github.com/gabrielfalcao/httpretty Author: Gabriel Falcao diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpretty-0.7.1/README.md new/httpretty-0.8.0/README.md --- old/httpretty-0.7.1/README.md 1970-01-01 01:00:00.000000000 +0100 +++ new/httpretty-0.8.0/README.md 2014-02-03 20:16:40.000000000 +0100 @@ -0,0 +1,474 @@ +# HTTPretty 0.8.0 + + +[](http://tip4commit.com/projects/133) +[](https://travis-ci.org/gabrielfalcao/HTTPretty) +[](http://instanc.es) +[ChangeLog](NEWS.md) + + +# Installing + +Since you are interested in HTTPretty you should also be insterested in speeding up your build. +Replace `pip` with [`curdling`](http://clarete.github.io/curdling/) and see your build running a lot faster. + +You can use curdling to install not only HTTPretty but every dependency in your project and see the speed gains. + +```bash +$ easy_install curdling +$ curd install HTTPretty +``` + +# In a nutshell + +Once upon a time a python developer wanted to use a RESTful api, +everything was fine but until the day they needed to test the code that +hits the RESTful API: what if the API server is down? What if its +content has changed ? + +Don't worry, HTTPretty is here for you: + +```python +import requests +from sure import expect +import httpretty + + [email protected] +def test_yipit_api_returning_deals(): + httpretty.register_uri(httpretty.GET, "http://api.yipit.com/v1/deals/", + body='[{"title": "Test Deal"}]', + content_type="application/json") + + response = requests.get('http://api.yipit.com/v1/deals/') + + expect(response.json()).to.equal([{"title": "Test Deal"}]) +``` + +# A more technical description + +HTTPretty is a HTTP client mock library for Python 100% inspired on ruby's [FakeWeb](http://fakeweb.rubyforge.org/). +If you come from ruby this would probably sound familiar :) + +# Usage + +## expecting a simple response body + +```python +import requests +import httpretty + +def test_one(): + httpretty.enable() # enable HTTPretty so that it will monkey patch the socket module + httpretty.register_uri(httpretty.GET, "http://yipit.com/", + body="Find the best daily deals") + + response = requests.get('http://yipit.com') + + assert response.text == "Find the best daily deals" + + httpretty.disable() # disable afterwards, so that you will have no problems in code that uses that socket module + httpretty.reset() # reset HTTPretty state (clean up registered urls and request history) +``` + +## testing query strings + +```python +import requests +from sure import expect +import httpretty + +def test_one(): + httpretty.enable() # enable HTTPretty so that it will monkey patch the socket module + httpretty.register_uri(httpretty.GET, "http://yipit.com/login", + body="Find the best daily deals") + + requests.get('http://yipit.com/[email protected]&password=foobar123') + expect(httpretty.last_request()).to.have.property("querystring").being.equal({ + "email": "[email protected]", + "password": "foobar123", + }) + + httpretty.disable() # disable afterwards, so that you will have no problems in code that uses that socket module +``` + + +## ohhhh, really? can that be easier? + +**YES** we've got a decorator + +```python +import requests +import httpretty + [email protected] +def test_one(): + httpretty.register_uri(httpretty.GET, "http://yipit.com/", + body="Find the best daily deals") + + response = requests.get('http://yipit.com') + assert response.text == "Find the best daily deals" +``` + +the `@httpretty.activate` is a short-hand decorator that wraps the +decorated function with httpretty.enable() and then calls +httpretty.disable() right after. + +## mocking the status code + +```python +import requests +from sure import expect +import httpretty + [email protected] +def test_github_access(): + httpretty.register_uri(httpretty.GET, "http://github.com/", + body="here is the mocked body", + status=201) + + response = requests.get('http://github.com') + expect(response.status_code).to.equal(201) +``` + +## you can tell HTTPretty to return any HTTP headers you want + +**and all you need is to add keyword args in which the keys are always lower-cased and with underscores `_` instead of dashes `-`** + +For example, let's say you want to mock that server returns `content-type`. +To do so, use the argument `content_type`, **all the keyword args are taken by HTTPretty and transformed in the RFC2616 equivalent name**. + +```python [email protected] +def test_some_api(): + httpretty.register_uri(httpretty.GET, "http://foo-api.com/gabrielfalcao", + body='{"success": false}', + status=500, + content_type='text/json') + + response = requests.get('http://foo-api.com/gabrielfalcao') + + expect(response.json()).to.equal({'success': False}) + expect(response.status_code).to.equal(500) +``` + + +### Adding extra headers and forcing headers + +You can pass the `adding_headers` argument as a dictionary and your +headers will be +[united](http://en.wikipedia.org/wiki/Union_(set_theory)) to the +existing headers. + +```python [email protected] +def test_some_api(): + httpretty.register_uri(httpretty.GET, "http://foo-api.com/gabrielfalcao", + body='{"success": false}', + status=500, + content_type='text/json', + adding_headers={ + 'X-foo': 'bar' + }) + + response = requests.get('http://foo-api.com/gabrielfalcao') + + expect(response.json()).to.equal({'success': False}) + expect(response.status_code).to.equal(500) +``` + +Although there are some situation where some headers line +`content-length` will be calculated by HTTPretty based on the +specified fake response body. + +So you might want to *"force"* those headers: + +```python [email protected] +def test_some_api(): + httpretty.register_uri(httpretty.GET, "http://foo-api.com/gabrielfalcao", + body='{"success": false}', + status=500, + content_type='text/json', + forcing_headers={ + 'content-length': '100' + }) + + response = requests.get('http://foo-api.com/gabrielfalcao') + + expect(response.json()).to.equal({'success': False}) + expect(response.status_code).to.equal(500) +``` + +You should, though, be careful with it. The HTTP client is likely to +rely on the content length to know how many bytes of response payload +should be loaded. Forcing a `content-length` that is bigger than the +action response body might cause the HTTP client to hang because it is +waiting for data. Read more in the "caveats" session on the bottom. + +## rotating responses + +Same URL, same request method, the first request return the first +httpretty.Response, all the subsequent ones return the last (status 202). + +Notice that the `responses` argument is a list and you can pass as +many responses as you want. + +```python +import requests +from sure import expect + + [email protected] +def test_rotating_responses(): + httpretty.register_uri(httpretty.GET, "http://github.com/gabrielfalcao/httpretty", + responses=[ + httpretty.Response(body="first response", status=201), + httpretty.Response(body='second and last response', status=202), + ]) + + response1 = requests.get('http://github.com/gabrielfalcao/httpretty') + expect(response1.status_code).to.equal(201) + expect(response1.text).to.equal('first response') + + response2 = requests.get('http://github.com/gabrielfalcao/httpretty') + expect(response2.status_code).to.equal(202) + expect(response2.text).to.equal('second and last response') + + response3 = requests.get('http://github.com/gabrielfalcao/httpretty') + + expect(response3.status_code).to.equal(202) + expect(response3.text).to.equal('second and last response') +``` +## streaming responses + +Mock a streaming response by registering a generator response body. + +```python +import requests +from sure import expect +import httpretty + +# mock a streaming response body with a generator +def mock_streaming_tweets(tweets): + from time import sleep + for t in tweets: + sleep(.5) + yield t + [email protected] +def test_twitter_api_integration(now): + twitter_response_lines = [ + '{"text":"If @BarackObama requests to follow me one more time I\'m calling the police."}\r\n', + '\r\n', + '{"text":"Thanks for all your #FollowMe1D requests Directioners! We\u2019ll be following 10 people throughout the day starting NOW. G ..."}\r\n' + ] + + TWITTER_STREAMING_URL = "https://stream.twitter.com/1/statuses/filter.json" + + # set the body to a generator and set `streaming=True` to mock a streaming response body + httpretty.register_uri(httpretty.POST, TWITTER_STREAMING_URL, + body=mock_streaming_tweets(twitter_response_lines), + streaming=True) + + # taken from the requests docs + # http://docs.python-requests.org/en/latest/user/advanced/#streaming-requests + response = requests.post(TWITTER_STREAMING_URL, data={'track':'requests'}, + auth=('username','password'), prefetch=False) + + #test iterating by line + line_iter = response.iter_lines() + for i in xrange(len(twitter_response_lines)): + expect(line_iter.next().strip()).to.equal(twitter_response_lines[i].strip()) +``` + +## dynamic responses through callbacks + +Set a callback to allow for dynamic responses based on the request. + +```python +import requests +from sure import expect +import httpretty + [email protected] +def test_response_callbacks(): + + def request_callback(method, uri, headers): + return (200, headers, "The {} response from {}".format(method, uri)) + + httpretty.register_uri( + httpretty.GET, "https://api.yahoo.com/test", + body=request_callback) + + response = requests.get('https://api.yahoo.com/test') + + expect(response.text).to.equal('The GET response from https://api.yahoo.com/test') +``` + +## matching regular expressions + +You can register a +[compiled regex](http://docs.python.org/2/library/re.html#re.compile) +and it will be matched against the requested urls. + +```python [email protected] +def test_httpretty_should_allow_registering_regexes(): + u"HTTPretty should allow registering regexes" + + httpretty.register_uri( + httpretty.GET, + re.compile("api.yipit.com/v2/deal;brand=(\w+)"), + body="Found brand", + ) + + response = requests.get('https://api.yipit.com/v2/deal;brand=GAP') + expect(response.text).to.equal('Found brand') + expect(httpretty.last_request().method).to.equal('GET') + expect(httpretty.last_request().path).to.equal('/v1/deal;brand=GAP') +``` + +By default, the regexp you register will match the requests without looking at +the querystring. If you want the querystring to be considered, you can set +`match_querystring=True` when calling `register_uri`. + +## expect for a response, and check the request got by the "server" to make sure it was fine. + +```python +import requests +from sure import expect +import httpretty + + [email protected] +def test_yipit_api_integration(): + httpretty.register_uri(httpretty.POST, "http://api.yipit.com/foo/", + body='{"repositories": ["HTTPretty", "lettuce"]}') + + response = requests.post('http://api.yipit.com/foo', + '{"username": "gabrielfalcao"}', + headers={ + 'content-type': 'text/json', + }) + + expect(response.text).to.equal('{"repositories": ["HTTPretty", "lettuce"]}') + expect(httpretty.last_request().method).to.equal("POST") + expect(httpretty.last_request().headers['content-type']).to.equal('text/json') +``` + +## checking if is enabled + +```python + +httpretty.enable() +httpretty.is_enabled().should.be.true + +httpretty.disable() +httpretty.is_enabled().should.be.false + +``` +# Motivation + +When building systems that access external resources such as RESTful +webservices, XMLRPC or even simple HTTP requests, we stumble in the +problem: + + "I'm gonna need to mock all those requests" + +It brings a lot of hassle, you will need to use a generic mocking +tool, mess with scope and so on. + +## The idea behind HTTPretty (how it works) + +HTTPretty [monkey patches](http://en.wikipedia.org/wiki/Monkey_patch) +Python's [socket](http://docs.python.org/library/socket.html) core +module, reimplementing the HTTP protocol, by mocking requests and +responses. + +As for it works in this way, you don't need to worry what http library +you're gonna use. + +HTTPretty will mock the response for you :) *(and also give you the latest requests so that you can check them)* + +# Acknowledgements + +## caveats with the [requests](http://docs.python-requests.org/en/latest/) library + +### `forcing_headers` + `Content-Length` + +if you use the `forcing_headers` options make sure to add the header +`Content-Length` otherwise the +[requests](http://docs.python-requests.org/en/latest/) will try to +load the response endlessly + +# Officially supported libraries + +Because HTTPretty works in the socket level it should work with any HTTP client libraries, although it is [battle tested](https://github.com/gabrielfalcao/HTTPretty/tree/master/tests/functional) against: + +* [requests](http://docs.python-requests.org/en/latest/) +* [httplib2](http://code.google.com/p/httplib2/) +* [urllib2](http://docs.python.org/2/library/urllib2.html) + +# Hacking on HTTPretty + +#### create a virtual env + +you will need [virtualenvwrapper](http://www.doughellmann.com/projects/virtualenvwrapper/) + + +```console +mkvirtualenv --distribute --no-site-packages HTTPretty +``` + +#### install the dependencies + +```console +pip install -r requirements.txt +``` + +#### next steps: + +1. run the tests with make: +```bash +make unit functional +``` +2. hack at will +3. commit, push etc +4. send a pull request + +# License + + <HTTPretty - HTTP client mock for Python> + Copyright (C) <2011-2013> Gabriel Falcão <[email protected]> + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + +# Main contributors + +There folks made remarkable contributions to HTTPretty: + +* Steve Pulec ~> @spulec +* Hugh Saunders ~> @hughsaunders +* Matt Luongo ~> @mhluongo +* James Rowe ~> @JNRowe diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpretty-0.7.1/dev-requirements.txt new/httpretty-0.8.0/dev-requirements.txt --- old/httpretty-0.7.1/dev-requirements.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/httpretty-0.8.0/dev-requirements.txt 2014-02-03 18:24:56.000000000 +0100 @@ -0,0 +1,2 @@ +markment +steadymark diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpretty-0.7.1/httpretty/__init__.py new/httpretty-0.8.0/httpretty/__init__.py --- old/httpretty-0.7.1/httpretty/__init__.py 2013-12-02 16:59:19.000000000 +0100 +++ new/httpretty-0.8.0/httpretty/__init__.py 2014-02-03 20:16:40.000000000 +0100 @@ -25,7 +25,7 @@ # OTHER DEALINGS IN THE SOFTWARE. from __future__ import unicode_literals -__version__ = version = '0.7.1' +__version__ = version = '0.8.0' from .core import httpretty, httprettified from .errors import HTTPrettyError diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpretty-0.7.1/httpretty/core.py new/httpretty-0.8.0/httpretty/core.py --- old/httpretty-0.7.1/httpretty/core.py 2013-12-02 16:59:19.000000000 +0100 +++ new/httpretty-0.8.0/httpretty/core.py 2014-02-03 20:16:40.000000000 +0100 @@ -166,6 +166,10 @@ # Now 2 convenient attributes for the HTTPretty API: # `querystring` holds a dictionary with the parsed query string + try: + self.path = self.path.encode('iso-8859-1') + except UnicodeDecodeError: + pass self.path = decode_utf8(self.path) qstring = self.path.split("?", 1)[-1] @@ -187,7 +191,7 @@ parsed = parse_qs(expanded) result = {} for k in parsed: - result[k] = map(decode_utf8, parsed[k]) + result[k] = list(map(decode_utf8, parsed[k])) return result @@ -204,6 +208,7 @@ content_type = self.headers.get('content-type', '') do_parse = PARSING_FUNCTIONS.get(content_type, FALLBACK_FUNCTION) + body = decode_utf8(body) try: return do_parse(body) except: @@ -344,7 +349,7 @@ try: requestline, _ = data.split(b'\r\n', 1) - method, path, version = parse_requestline(requestline) + method, path, version = parse_requestline(decode_utf8(requestline)) is_parsing_headers = True except ValueError: is_parsing_headers = False @@ -358,10 +363,10 @@ if not is_parsing_headers: if len(self._sent_data) > 1: headers = utf8(last_requestline(self._sent_data)) - meta = dict(self._entry.request.headers) + meta = self._entry.request.headers body = utf8(self._sent_data[-1]) if meta.get('transfer-encoding', '') == 'chunked': - if not body.isdigit() and body != '\r\n' and body != '0\r\n\r\n': + if not body.isdigit() and body != b'\r\n' and body != b'0\r\n\r\n': self._entry.request.body += body else: self._entry.request.body += body @@ -372,7 +377,7 @@ # path might come with s = urlsplit(path) POTENTIAL_HTTP_PORTS.add(int(s.port or 80)) - headers, body = map(utf8, data.split(b'\r\n\r\n', 1)) + headers, body = list(map(utf8, data.split(b'\r\n\r\n', 1))) request = httpretty.historify_request(headers, body) @@ -393,7 +398,7 @@ def debug(self, func, *a, **kw): if self.is_http: frame = inspect.stack()[0][0] - lines = map(utf8, traceback.format_stack(frame)) + lines = list(map(utf8, traceback.format_stack(frame))) message = [ "HTTPretty intercepted and unexpected socket method call.", @@ -807,12 +812,12 @@ 'uri': uri, 'method': request.method, 'headers': dict(request.headers), - 'body': request.body, + 'body': decode_utf8(request.body), 'querystring': request.querystring }, 'response': { 'status': response.status, - 'body': response.data, + 'body': decode_utf8(response.data), 'headers': dict(response.headers) } }) @@ -843,6 +848,8 @@ @classmethod def reset(cls): + global POTENTIAL_HTTP_PORTS + POTENTIAL_HTTP_PORTS = set([80, 443]) cls._entries.clear() cls.latest_requests = [] cls.last_request = HTTPrettyRequestEmpty() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpretty-0.7.1/httpretty/http.py new/httpretty-0.8.0/httpretty/http.py --- old/httpretty-0.7.1/httpretty/http.py 2013-11-21 04:03:00.000000000 +0100 +++ new/httpretty-0.8.0/httpretty/http.py 2014-02-03 20:16:40.000000000 +0100 @@ -27,6 +27,7 @@ import re from .compat import BaseClass +from .utils import decode_utf8 STATUSES = { @@ -109,14 +110,14 @@ class HttpBaseClass(BaseClass): - GET = b'GET' - PUT = b'PUT' - POST = b'POST' - DELETE = b'DELETE' - HEAD = b'HEAD' - PATCH = b'PATCH' - OPTIONS = b'OPTIONS' - CONNECT = b'CONNECT' + GET = 'GET' + PUT = 'PUT' + POST = 'POST' + DELETE = 'DELETE' + HEAD = 'HEAD' + PATCH = 'PATCH' + OPTIONS = 'OPTIONS' + CONNECT = 'CONNECT' METHODS = (GET, PUT, POST, DELETE, HEAD, PATCH, OPTIONS, CONNECT) @@ -133,8 +134,8 @@ ... ValueError: Not a Request-Line """ - methods = b'|'.join(HttpBaseClass.METHODS) - m = re.match(br'(' + methods + b')\s+(.*)\s+HTTP/(1.[0|1])', s, re.I) + methods = '|'.join(HttpBaseClass.METHODS) + m = re.match(r'(' + methods + ')\s+(.*)\s+HTTP/(1.[0|1])', s, re.I) if m: return m.group(1).upper(), m.group(2), m.group(3) else: @@ -147,7 +148,7 @@ """ for line in reversed(sent_data): try: - parse_requestline(line) + parse_requestline(decode_utf8(line)) except ValueError: pass else: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpretty-0.7.1/httpretty.egg-info/PKG-INFO new/httpretty-0.8.0/httpretty.egg-info/PKG-INFO --- old/httpretty-0.7.1/httpretty.egg-info/PKG-INFO 2013-12-12 18:25:48.000000000 +0100 +++ new/httpretty-0.8.0/httpretty.egg-info/PKG-INFO 2014-02-03 20:17:12.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: httpretty -Version: 0.7.1 +Version: 0.8.0 Summary: HTTP client mock for Python Home-page: http://github.com/gabrielfalcao/httpretty Author: Gabriel Falcao diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpretty-0.7.1/httpretty.egg-info/SOURCES.txt new/httpretty-0.8.0/httpretty.egg-info/SOURCES.txt --- old/httpretty-0.7.1/httpretty.egg-info/SOURCES.txt 2013-12-12 18:25:48.000000000 +0100 +++ new/httpretty-0.8.0/httpretty.egg-info/SOURCES.txt 2014-02-03 20:17:12.000000000 +0100 @@ -1,6 +1,13 @@ +COPYING MANIFEST.in +Makefile +README.md +dev-requirements.txt requirements.txt +setup.cfg setup.py +test-requirements.txt +tox.ini httpretty/__init__.py httpretty/compat.py httpretty/core.py @@ -23,6 +30,7 @@ tests/functional/test_requests.py tests/functional/test_urllib2.py tests/functional/testserver.py +tests/functional/fixtures/playback-1.json tests/unit/__init__.py tests/unit/test_core.py tests/unit/test_http.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpretty-0.7.1/httpretty.egg-info/top_level.txt new/httpretty-0.8.0/httpretty.egg-info/top_level.txt --- old/httpretty-0.7.1/httpretty.egg-info/top_level.txt 2013-12-12 18:25:48.000000000 +0100 +++ new/httpretty-0.8.0/httpretty.egg-info/top_level.txt 2014-02-03 20:17:12.000000000 +0100 @@ -1,2 +1 @@ httpretty -tests diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpretty-0.7.1/requirements.txt new/httpretty-0.8.0/requirements.txt --- old/httpretty-0.7.1/requirements.txt 2013-12-12 17:45:55.000000000 +0100 +++ new/httpretty-0.8.0/requirements.txt 2014-02-03 18:24:56.000000000 +0100 @@ -1,29 +1 @@ -bolacha==0.6.0 -couleur==0.5.0 -coverage==3.5.3 -cssselect==0.8 -distribute==0.6.30 -Flask==0.9 -httplib2==0.7.6 -ipdb==0.7 -ipython==0.13.1 -Jinja2==2.6 -lxml==3.1.2 -markment==0.2.14 -misaka==1.0.2 -mock==1.0.1 -multiprocessing==2.6.2.1 -nose==1.2.1 -py==1.4.12 -Pygments==1.6 -python-qt==0.50 -PyYAML==3.10 -redis==2.7.1 -requests==1.1.0 -speakers==0.0.3 -steadymark==0.4.5 -tornado==2.4 -tox==1.4.2 -virtualenv==1.8.2 -Werkzeug==0.9.1 -sure==1.2.2 +urllib3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpretty-0.7.1/setup.cfg new/httpretty-0.8.0/setup.cfg --- old/httpretty-0.7.1/setup.cfg 2013-12-12 18:25:48.000000000 +0100 +++ new/httpretty-0.8.0/setup.cfg 2014-02-03 20:17:12.000000000 +0100 @@ -1,3 +1,10 @@ +[nosetests] +verbosity = 2 +with-coverage = 1 +cover-erase = 1 +cover-package = httpretty +cover-inclusive = 1 + [egg_info] tag_build = tag_date = 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpretty-0.7.1/setup.py new/httpretty-0.8.0/setup.py --- old/httpretty-0.7.1/setup.py 2013-12-12 17:45:10.000000000 +0100 +++ new/httpretty-0.8.0/setup.py 2014-02-03 20:16:40.000000000 +0100 @@ -28,20 +28,20 @@ import os from httpretty import version, HTTPretty -from setuptools import setup, find_packages +from setuptools import setup HTTPretty.disable() HTTPRETTY_PATH = os.path.abspath(os.path.join(__file__, os.pardir)) -def test_packages(): - test_reqs = os.path.join(HTTPRETTY_PATH, 'requirements.txt') - tests_require = [ - line.strip() for line in open(test_reqs).readlines() - if not line.startswith("#") - ] - return tests_require +def parse_requirements(reqs_path): + target_path = os.path.join(HTTPRETTY_PATH, reqs_path) + return [ + line.strip() for line in open(target_path).readlines() + if not line.startswith("#") + ] + setup(name='httpretty', version=version, @@ -50,10 +50,11 @@ author_email='[email protected]', url='http://github.com/gabrielfalcao/httpretty', zip_safe=False, - packages=find_packages(HTTPRETTY_PATH, ('tests')), - tests_require=test_packages(), - install_requires=['urllib3'], + packages=['httpretty'], + tests_require=parse_requirements('test-requirements.txt'), + install_requires=parse_requirements('requirements.txt'), license='MIT', + test_suite='nose.collector', classifiers=["Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Topic :: Software Development :: Testing"], diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpretty-0.7.1/test-requirements.txt new/httpretty-0.8.0/test-requirements.txt --- old/httpretty-0.7.1/test-requirements.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/httpretty-0.8.0/test-requirements.txt 2014-02-03 18:24:56.000000000 +0100 @@ -0,0 +1,12 @@ +# test runner +coverage +nose + +# testing utilities +mock +sure + +# external frameworks tested against +httplib2 +requests +tornado diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpretty-0.7.1/tests/functional/fixtures/playback-1.json new/httpretty-0.8.0/tests/functional/fixtures/playback-1.json --- old/httpretty-0.7.1/tests/functional/fixtures/playback-1.json 1970-01-01 01:00:00.000000000 +0100 +++ new/httpretty-0.8.0/tests/functional/fixtures/playback-1.json 2014-02-03 18:24:56.000000000 +0100 @@ -0,0 +1,58 @@ +[ + { + "request": { + "body": "", + "headers": { + "host": "localhost:8888", + "accept-encoding": "gzip, deflate, compress", + "content-length": "0", + "accept": "*/*", + "user-agent": "python-requests/1.1.0 CPython/2.7.5 Darwin/12.5.0" + }, + "querystring": { + "age": [ + "25" + ], + "name": [ + "Gabriel" + ] + }, + "uri": "http://localhost:8888/foobar?name=Gabriel&age=25", + "method": "GET" + }, + "response": { + "status": 200, + "body": "{\n \"foobar\": {\n \"age\": \"25\", \n \"name\": \"Gabriel\"\n }\n}", + "headers": { + "content-length": "73", + "etag": "\"6fdccaba6542114e7d1098d22a01623dc2aa5761\"", + "content-type": "text/html; charset=UTF-8", + "server": "TornadoServer/2.4" + } + } + }, + { + "request": { + "body": "{\"test\": \"123\"}", + "headers": { + "host": "localhost:8888", + "accept-encoding": "gzip, deflate, compress", + "content-length": "15", + "accept": "*/*", + "user-agent": "python-requests/1.1.0 CPython/2.7.5 Darwin/12.5.0" + }, + "querystring": {}, + "uri": "http://localhost:8888/foobar", + "method": "POST" + }, + "response": { + "status": 200, + "body": "{\n \"foobar\": {}\n}", + "headers": { + "content-length": "20", + "content-type": "text/html; charset=UTF-8", + "server": "TornadoServer/2.4" + } + } + } +] \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpretty-0.7.1/tests/functional/test_requests.py new/httpretty-0.8.0/tests/functional/test_requests.py --- old/httpretty-0.7.1/tests/functional/test_requests.py 2013-11-21 04:03:00.000000000 +0100 +++ new/httpretty-0.8.0/tests/functional/test_requests.py 2014-02-03 20:16:40.000000000 +0100 @@ -32,10 +32,13 @@ import json import requests from sure import within, microseconds, expect +from tornado import version as tornado_version from httpretty import HTTPretty, httprettified +from httpretty.compat import text_type from httpretty.core import decode_utf8 -from base import FIXTURE_FILE, use_tornado_server +from .base import FIXTURE_FILE, use_tornado_server +from tornado import version as tornado_version try: xrange = xrange @@ -459,7 +462,7 @@ response = requests.get('https://api.yahoo.com/test') expect(response.text).to.equal("The GET response from https://api.yahoo.com/test") expect(response.headers).to.have.key('a').being.equal("b") - expect(response.status_code).to.be(418) + expect(response.status_code).to.equal(418) HTTPretty.register_uri( HTTPretty.POST, "https://api.yahoo.com/test_post", @@ -472,7 +475,7 @@ expect(response.text).to.equal("The POST response from https://api.yahoo.com/test_post") expect(response.headers).to.have.key('a').being.equal("b") - expect(response.status_code).to.be(418) + expect(response.status_code).to.equal(418) @httprettified def test_httpretty_should_allow_registering_regexes_and_give_a_proper_match_to_the_callback(): @@ -572,7 +575,7 @@ os.environ['DEBUG'] = 'true' def my_callback(request, url, headers): - request.body.should.equal('hithere') + request.body.should.equal(b'hithere') return 200, headers, "Received" HTTPretty.register_uri( @@ -589,7 +592,7 @@ 'https://api.yipit.com/v1/deal;brand=gap?first_name=chuck&last_name=norris', data=gen(), ) - expect(response.content).to.equal("Received") + expect(response.content).to.equal(b"Received") expect(HTTPretty.last_request.method).to.equal('POST') expect(HTTPretty.last_request.path).to.equal('/v1/deal;brand=gap?first_name=chuck&last_name=norris') @@ -696,9 +699,9 @@ ] }) response['response'].should.have.key("status").being.equal(200) - response['response'].should.have.key("body").being.an(unicode) + response['response'].should.have.key("body").being.an(text_type) response['response'].should.have.key("headers").being.a(dict) - response['response']["headers"].should.have.key("server").being.equal("TornadoServer/2.4") + response['response']["headers"].should.have.key("server").being.equal("TornadoServer/" + tornado_version) def test_playing_calls(): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpretty-0.7.1/tests/unit/test_core.py new/httpretty-0.8.0/tests/unit/test_core.py --- old/httpretty-0.7.1/tests/unit/test_core.py 2013-12-02 16:59:19.000000000 +0100 +++ new/httpretty-0.8.0/tests/unit/test_core.py 2014-02-03 20:16:40.000000000 +0100 @@ -8,6 +8,7 @@ from mock import Mock, patch, call from sure import expect +from httpretty.compat import StringIO from httpretty.core import HTTPrettyRequest, FakeSSLSocket, fakesock, httpretty @@ -23,11 +24,11 @@ # Given a valid HTTP request header string headers = "\r\n".join([ 'POST /somewhere/?name=foo&age=bar HTTP/1.1', - 'Accept-Encoding: identity', - 'Host: github.com', - 'Content-Type: application/json', - 'Connection: close', - 'User-Agent: Python-urllib/2.7', + 'accept-encoding: identity', + 'host: github.com', + 'content-type: application/json', + 'connection: close', + 'user-agent: Python-urllib/2.7', ]) # When I create a HTTPrettyRequest with an empty body @@ -43,10 +44,12 @@ }) # And the `rfile` should be a StringIO - request.should.have.property('rfile').being.a('StringIO.StringIO') + type_as_str = StringIO.__module__ + '.' + StringIO.__name__ + + request.should.have.property('rfile').being.a(type_as_str) # And the `wfile` should be a StringIO - request.should.have.property('wfile').being.a('StringIO.StringIO') + request.should.have.property('wfile').being.a(type_as_str) # And the `method` should be available request.should.have.property('method').being.equal('POST') @@ -301,16 +304,16 @@ # Background: the real socket will stop returning bytes after the # first call real_socket = old_socket.return_value - real_socket.recv.side_effect = ['response from server', ""] + real_socket.recv.side_effect = [b'response from server', b""] # Given a fake socket socket = fakesock.socket() # When I call real_sendall with data, some args and kwargs - socket.real_sendall("SOMEDATA", 'some extra args...', foo='bar') + socket.real_sendall(b"SOMEDATA", b'some extra args...', foo=b'bar') # Then it should have called sendall in the real socket - real_socket.sendall.assert_called_once_with("SOMEDATA", 'some extra args...', foo='bar') + real_socket.sendall.assert_called_once_with(b"SOMEDATA", b'some extra args...', foo=b'bar') # And the timeout was set to 0 real_socket.settimeout.assert_called_once_with(0) @@ -322,7 +325,7 @@ ]) # And the buffer should contain the data from the server - socket.fd.getvalue().should.equal("response from server") + socket.fd.getvalue().should.equal(b"response from server") # And connect was never called real_socket.connect.called.should.be.false @@ -336,17 +339,17 @@ # Background: the real socket will stop returning bytes after the # first call real_socket = old_socket.return_value - real_socket.recv.side_effect = [SocketErrorStub(errno.EAGAIN), 'after error', ""] + real_socket.recv.side_effect = [SocketErrorStub(errno.EAGAIN), b'after error', b""] # Given a fake socket socket = fakesock.socket() # When I call real_sendall with data, some args and kwargs - socket.real_sendall("SOMEDATA", 'some extra args...', foo='bar') + socket.real_sendall(b"SOMEDATA", b'some extra args...', foo=b'bar') # Then it should have called sendall in the real socket - real_socket.sendall.assert_called_once_with("SOMEDATA", 'some extra args...', foo='bar') + real_socket.sendall.assert_called_once_with(b"SOMEDATA", b'some extra args...', foo=b'bar') # And the timeout was set to 0 real_socket.settimeout.assert_called_once_with(0) @@ -358,7 +361,7 @@ ]) # And the buffer should contain the data from the server - socket.fd.getvalue().should.equal("after error") + socket.fd.getvalue().should.equal(b"after error") # And connect was never called real_socket.connect.called.should.be.false @@ -372,16 +375,16 @@ # Background: the real socket will stop returning bytes after the # first call real_socket = old_socket.return_value - real_socket.recv.side_effect = [SocketErrorStub(42), 'after error', ""] + real_socket.recv.side_effect = [SocketErrorStub(42), b'after error', ""] # Given a fake socket socket = fakesock.socket() # When I call real_sendall with data, some args and kwargs - socket.real_sendall("SOMEDATA", 'some extra args...', foo='bar') + socket.real_sendall(b"SOMEDATA", b'some extra args...', foo=b'bar') # Then it should have called sendall in the real socket - real_socket.sendall.assert_called_once_with("SOMEDATA", 'some extra args...', foo='bar') + real_socket.sendall.assert_called_once_with(b"SOMEDATA", b'some extra args...', foo=b'bar') # And the timeout was set to 0 real_socket.settimeout.assert_called_once_with(0) @@ -390,7 +393,7 @@ real_socket.recv.assert_called_once_with(16) # And the buffer should contain the data from the server - socket.fd.getvalue().should.equal("") + socket.fd.getvalue().should.equal(b"") # And connect was never called real_socket.connect.called.should.be.false @@ -403,7 +406,7 @@ # Background: the real socket will stop returning bytes after the # first call real_socket = old_socket.return_value - real_socket.recv.side_effect = ['response from foobar :)', ""] + real_socket.recv.side_effect = [b'response from foobar :)', b""] # And the potential http port is 4000 POTENTIAL_HTTP_PORTS.__contains__.side_effect = lambda other: int(other) == 4000 @@ -415,7 +418,7 @@ socket.connect(('foobar.com', 4000)) # And send some data - socket.real_sendall("SOMEDATA") + socket.real_sendall(b"SOMEDATA") # Then connect should have been called real_socket.connect.assert_called_once_with(('foobar.com', 4000)) @@ -430,7 +433,7 @@ ]) # And the buffer should contain the data from the server - socket.fd.getvalue().should.equal("response from foobar :)") + socket.fd.getvalue().should.equal(b"response from foobar :)") @patch('httpretty.core.old_socket') @@ -456,7 +459,7 @@ socket.connect(('foo.com', 80)) # When I try to send data - socket.sendall("GET /foobar HTTP/1.1\r\nContent-Type: application/json\r\n\r\n") + socket.sendall(b"GET /foobar HTTP/1.1\r\nContent-Type: application/json\r\n\r\n") @patch('httpretty.core.old_socket') @@ -482,7 +485,7 @@ socket.connect(('foo.com', 80)) # When I try to send data - socket.sendall("GET /foobar HTTP/1.1\r\nContent-Type: application/json\r\n\r\n") + socket.sendall(b"GET /foobar HTTP/1.1\r\nContent-Type: application/json\r\n\r\n") @patch('httpretty.core.old_socket') @@ -493,7 +496,7 @@ # Using a subclass of socket that mocks out real_sendall class MySocket(fakesock.socket): def real_sendall(self, data): - data.should.equal('BLABLABLABLA') + data.should.equal(b'BLABLABLABLA') return 'cool' # Given an instance of that socket @@ -504,7 +507,7 @@ socket.connect(('foo.com', 80)) # When I try to send data - result = socket.sendall("BLABLABLABLA") + result = socket.sendall(b"BLABLABLABLA") # Then the result should be the return value from real_sendall result.should.equal('cool') @@ -522,7 +525,7 @@ # Using a mocked entry entry = Mock() entry.request.headers = {} - entry.request.body = '' + entry.request.body = b'' # Given an instance of that socket socket = MySocket() @@ -533,10 +536,10 @@ socket.connect(('foo.com', 80)) # When I try to send data - socket.sendall("BLABLABLABLA") + socket.sendall(b"BLABLABLABLA") # Then the entry should have that body - entry.request.body.should.equal('BLABLABLABLA') + entry.request.body.should.equal(b'BLABLABLABLA') @patch('httpretty.core.old_socket') @@ -553,7 +556,7 @@ entry.request.headers = { 'transfer-encoding': 'chunked', } - entry.request.body = '' + entry.request.body = b'' # Given an instance of that socket socket = MySocket() @@ -563,7 +566,7 @@ socket.connect(('foo.com', 80)) # When I try to send data - socket.sendall("BLABLABLABLA") + socket.sendall(b"BLABLABLABLA") # Then the entry should have that body - httpretty.last_request.body.should.equal('BLABLABLABLA') + httpretty.last_request.body.should.equal(b'BLABLABLABLA') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpretty-0.7.1/tox.ini new/httpretty-0.8.0/tox.ini --- old/httpretty-0.7.1/tox.ini 1970-01-01 01:00:00.000000000 +0100 +++ new/httpretty-0.8.0/tox.ini 2014-02-03 18:24:56.000000000 +0100 @@ -0,0 +1,14 @@ +[tox] +envlist = py26, py27 + +[testenv] +deps = -r{toxinidir}/test-requirements.txt + -r{toxinidir}/requirements.txt +commands = nosetests -s tests/unit + +[testenv:functional] +commands = nosetests -s tests/functional + +[testenv:pep8] +deps = flake8 +commands = flake8 httpretty tests -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
