summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/.markment.yml23
-rw-r--r--docs/NEWS.md80
-rw-r--r--docs/about.md18
-rw-r--r--docs/contributing.md62
-rw-r--r--docs/docs.md299
-rw-r--r--docs/intro.md82
6 files changed, 564 insertions, 0 deletions
diff --git a/docs/.markment.yml b/docs/.markment.yml
new file mode 100644
index 0000000..f669aba
--- /dev/null
+++ b/docs/.markment.yml
@@ -0,0 +1,23 @@
+project:
+ name: "HTTPretty"
+ version: 0.7.0
+ description: HTTP request mock tool for python
+ tagline: Intercept real HTTP calls in python, test your software better.
+ twitter: gabrielfalcao
+ twitter_message: Python%20library%20for%20intercepting%20and%20mocking%20HTTP%20calls
+ google_analytics_code: UA-1277640-14
+ github_maintainer: gabrielfalcao
+ github_maintainer_name: Gabriel Falcão
+ github_maintainer_url: http://github.com/gabrielfalcao
+ github_maintainer_gravatar: https://secure.gravatar.com/avatar/3fa0df5c54f5ac0f8652d992d7d24039?s=64
+
+ github_url: http://github.com/gabrielfalcao/HTTPretty
+ github_fork_url: https://github.com/gabrielfalcao/HTTPretty/archive/master.tar.gz
+ tarball_download_url: https://github.com/gabrielfalcao/HTTPretty/archive/master.tar.gz
+ zipball_download_url: https://github.com/gabrielfalcao/HTTPretty/archive/master.zip
+ documentation_url: http://falcao.it/HTTPretty
+ support_url: http://github.com/gabrielfalcao/HTTPretty/issues
+ logo_url: https://s3-us-west-2.amazonaws.com/s.cdpn.io/18885/httpretty-logo_1.svg
+ full_index: false
+documentation:
+ index: intro.md
diff --git a/docs/NEWS.md b/docs/NEWS.md
new file mode 100644
index 0000000..d8fb0e1
--- /dev/null
+++ b/docs/NEWS.md
@@ -0,0 +1,80 @@
+# Release Notes
+
+## 0.7.0 (current)
+
+Improvements:
+
+* Refactored `core.py` and increased its unit test coverage to 80%. HTTPretty is slightly more robust now.
+
+Bug fixes:
+
+* POST requests being called twice [#100](https://github.com/gabrielfalcao/HTTPretty/pull/100)
+
+## 0.6.5
+
+Applied pull requests:
+
+* continue on EAGAIN socket errors: [#102](https://github.com/gabrielfalcao/HTTPretty/pull/102) by [kouk](http://github.com/kouk).
+* Fix `fake_gethostbyname` for requests 2.0: [#101](https://github.com/gabrielfalcao/HTTPretty/pull/101) by [mgood](http://github.com/mgood)
+* Add a way to match the querystrings: [#98](https://github.com/gabrielfalcao/HTTPretty/pull/98) by [ametaireau](http://github.com/ametaireau)
+* Use common string case for URIInfo hostname comparison: [#95](https://github.com/gabrielfalcao/HTTPretty/pull/95) by [mikewaters](http://github.com/mikewaters)
+* Expose httpretty.reset() to public API: [#91](https://github.com/gabrielfalcao/HTTPretty/pull/91) by [imankulov](http://github.com/imankulov)
+* Don't duplicate http ports number: [#89](https://github.com/gabrielfalcao/HTTPretty/pull/89) by [mardiros](http://github.com/mardiros)
+* Adding parsed_body parameter to simplify checks: [#88](https://github.com/gabrielfalcao/HTTPretty/pull/88) by [toumorokoshi](http://github.com/toumorokoshi)
+* Use the real socket if it's not HTTP: [#87](https://github.com/gabrielfalcao/HTTPretty/pull/87) by [mardiros](http://github.com/mardiros)
+
+## 0.6.2
+
+* Fixing bug of lack of trailing slashes [#73](https://github.com/gabrielfalcao/HTTPretty/issues/73)
+* Applied pull requests [#71](https://github.com/gabrielfalcao/HTTPretty/pull/71) and [#72](https://github.com/gabrielfalcao/HTTPretty/pull/72) by @andresriancho
+* Keyword arg coercion fix by @dupuy
+* @papaeye fixed content-length calculation.
+
+## 0.6.1
+
+* New API, no more camel case and everything is available through a simple import:
+
+```python
+import httpretty
+
+@httpretty.activate
+def test_function():
+ # httpretty.register_uri(...)
+ # make request...
+ pass
+```
+
+* Re-organized module into submodules
+
+## 0.5.14
+
+* Delegate calls to other methods on socket
+
+* [Normalized header](https://github.com/gabrielfalcao/HTTPretty/pull/49) strings
+
+* Callbacks are [more intelligent now](https://github.com/gabrielfalcao/HTTPretty/pull/47)
+
+* Normalize urls matching for url quoting
+
+## 0.5.12
+
+* HTTPretty doesn't hang when using other application protocols under
+ a @httprettified decorated test.
+
+## 0.5.11
+
+* Ability to know whether HTTPretty is or not enabled through `httpretty.is_enabled()`
+
+## 0.5.10
+
+* Support to multiple methods per registered URL. Thanks @hughsaunders
+
+## 0.5.9
+
+* Fixed python 3 support. Thanks @spulec
+
+## 0.5.8
+
+* Support to [register regular expressions to match urls](#matching-regular-expressions)
+* [Body callback](#dynamic-responses-through-callbacks) suppport
+* Python 3 support
diff --git a/docs/about.md b/docs/about.md
new file mode 100644
index 0000000..44b87a7
--- /dev/null
+++ b/docs/about.md
@@ -0,0 +1,18 @@
+# Acknowledgements
+
+## caveats
+
+### `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
+
+## 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)
diff --git a/docs/contributing.md b/docs/contributing.md
new file mode 100644
index 0000000..e4ed3ae
--- /dev/null
+++ b/docs/contributing.md
@@ -0,0 +1,62 @@
+# Hacking on HTTPretty
+
+## creating a virtual env
+
+you will need [virtualenvwrapper](http://www.doughellmann.com/projects/virtualenvwrapper/)
+
+
+```console
+mkvirtualenv --distribute --no-site-packages HTTPretty
+```
+
+## installing the dependencies
+
+```console
+pip install -r requirements.pip
+```
+
+## 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 <gabriel@nacaolivre.org>
+
+ 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 --git a/docs/docs.md b/docs/docs.md
new file mode 100644
index 0000000..c87f401
--- /dev/null
+++ b/docs/docs.md
@@ -0,0 +1,299 @@
+# Reference
+
+## 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/login?email=user@github.com&password=foobar123')
+ expect(httpretty.last_request()).to.have.property("querystring").being.equal({
+ "email": "user@github.com",
+ "password": "foobar123",
+ })
+
+ httpretty.disable() # disable afterwards, so that you will have no problems in code that uses that socket module
+```
+
+
+## Using the decorator
+
+**YES** we've got a decorator
+
+```python
+import requests
+import httpretty
+
+@httpretty.activate
+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.
+
+## Providing status code
+
+```python
+import requests
+from sure import expect
+import httpretty
+
+@httpretty.activate
+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)
+```
+
+## Providing custom heades
+
+**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
+@httpretty.activate
+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
+@httpretty.activate
+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
+@httpretty.activate
+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
+
+
+@httpretty.activate
+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
+
+@httpretty.activate
+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
+
+@httpretty.activate
+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
+@httpretty.activate
+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
+
+
+@httpretty.activate
+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
+
+```
diff --git a/docs/intro.md b/docs/intro.md
new file mode 100644
index 0000000..7187a65
--- /dev/null
+++ b/docs/intro.md
@@ -0,0 +1,82 @@
+# What is HTTPretty ?
+
+Once upon a time a python developer wanted to use a RESTful api,
+everything was fine but until the day he 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
+
+
+@httpretty.activate
+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 :smiley:
+
+## Installing
+
+Installing httpretty is as easy as:
+
+```bash
+pip install HTTPretty
+```
+
+# Demo
+
+## 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)
+```
+
+# 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)*