summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Dygalo <dadygalo@gmail.com>2016-02-02 12:02:37 +0100
committerDmitry Dygalo <dadygalo@gmail.com>2016-02-02 13:24:05 +0100
commit6c2942b19865106a3ac65b3bfc1fc93aae2d346c (patch)
tree7c53d4af130cf3a7b9d1d4b1ad7d54ad148795eb
parented8cfd33e65fc7b477f038e921c967f1698448fd (diff)
downloadpython-requests-6c2942b19865106a3ac65b3bfc1fc93aae2d346c.tar.gz
Initial work
-rw-r--r--.coveragerc7
-rw-r--r--.gitignore1
-rw-r--r--AUTHORS.rst3
-rw-r--r--Makefile4
-rwxr-xr-xsetup.py35
-rwxr-xr-xtest_requests.py275
-rw-r--r--tox.ini8
7 files changed, 172 insertions, 161 deletions
diff --git a/.coveragerc b/.coveragerc
new file mode 100644
index 00000000..343de18d
--- /dev/null
+++ b/.coveragerc
@@ -0,0 +1,7 @@
+[run]
+omit = */packages/*
+
+[report]
+show_missing = true
+precision = 2
+exclude_lines = pytest.fail \ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 9fcc6c3d..61da8789 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,7 +5,6 @@ nosetests.xml
junit-report.xml
pylint.txt
toy.py
-tox.ini
violations.pyflakes.txt
cover/
build/
diff --git a/AUTHORS.rst b/AUTHORS.rst
index 7d0ac65a..fc760599 100644
--- a/AUTHORS.rst
+++ b/AUTHORS.rst
@@ -162,4 +162,5 @@ Patches and Suggestions
- Smiley Barry (`@smiley <https://github.com/smiley>`_)
- Shagun Sodhani (`@shagunsodhani <https://github.com/shagunsodhani>`_)
- Robin Linderborg (`@vienno <https://github.com/vienno>`_)
-- Brian Samek(`@bsamek <https://github.com/bsamek`_)
+- Brian Samek (`@bsamek <https://github.com/bsamek>`_)
+- Dmitry Dygalo (`@Stranger6667 <https://github.com/Stranger6667>`_)
diff --git a/Makefile b/Makefile
index dea33a3f..cdc99e95 100644
--- a/Makefile
+++ b/Makefile
@@ -6,10 +6,10 @@ init:
test:
# This runs all of the tests. To run an individual test, run py.test with
# the -k flag, like "py.test -k test_path_is_not_double_encoded"
- py.test test_requests.py
+ python setup.py test -a "test_requests.py"
coverage:
- py.test --verbose --cov-report term --cov=requests test_requests.py
+ python setup.py test -a "--verbose --cov-report term --cov=requests test_requests.py"
ci: init
py.test --junitxml=junit.xml
diff --git a/setup.py b/setup.py
index d90f4b01..bf729290 100755
--- a/setup.py
+++ b/setup.py
@@ -1,12 +1,36 @@
#!/usr/bin/env python
import os
+import platform
import re
import sys
from codecs import open
from setuptools import setup
+from setuptools.command.test import test as TestCommand
+
+
+JYTHON = platform.system() == 'Java'
+
+
+class PyTest(TestCommand):
+ user_options = [('pytest-args=', 'a', "Arguments to pass into py.test")]
+
+ def initialize_options(self):
+ TestCommand.initialize_options(self)
+ self.pytest_args = []
+
+ def finalize_options(self):
+ TestCommand.finalize_options(self)
+ self.test_args = []
+ self.test_suite = True
+
+ def run_tests(self):
+ import pytest
+
+ errno = pytest.main(self.pytest_args)
+ sys.exit(errno)
if sys.argv[-1] == 'publish':
@@ -25,8 +49,11 @@ packages = [
]
requires = []
+test_requirements = ['pytest>=2.8.0', 'pytest-httpbin==0.0.7']
+
+if not JYTHON:
+ test_requirements.append('pytest-cov')
-version = ''
with open('requests/__init__.py', 'r') as fd:
version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]',
fd.read(), re.MULTILINE).group(1)
@@ -60,12 +87,18 @@ setup(
'Natural Language :: English',
'License :: OSI Approved :: Apache Software License',
'Programming Language :: Python',
+ 'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Programming Language :: Python :: Implementation :: PyPy',
+ 'Programming Language :: Python :: Implementation :: Jython',
),
+ cmdclass={'test': PyTest},
+ tests_require=test_requirements,
extras_require={
'security': ['pyOpenSSL>=0.13', 'ndg-httpsclient', 'pyasn1'],
},
diff --git a/test_requests.py b/test_requests.py
index 27f4929b..356fb795 100755
--- a/test_requests.py
+++ b/test_requests.py
@@ -7,7 +7,6 @@ from __future__ import division
import json
import os
import pickle
-import unittest
import collections
import contextlib
@@ -74,17 +73,8 @@ def httpsbin_url(httpbin_secure):
# listening on that port)
TARPIT = "http://10.255.255.1"
-class TestRequests(object):
- _multiprocess_can_split_ = True
-
- def setUp(self):
- """Create simple data set with headers."""
- pass
-
- def tearDown(self):
- """Teardown."""
- pass
+class TestRequests:
def test_entry_points(self):
@@ -97,17 +87,19 @@ class TestRequests(object):
requests.patch
requests.post
- def test_invalid_url(self):
- with pytest.raises(MissingSchema):
- requests.get('hiwpefhipowhefopw')
- with pytest.raises(InvalidSchema):
- requests.get('localhost:3128')
- with pytest.raises(InvalidSchema):
- requests.get('localhost.localdomain:3128/')
- with pytest.raises(InvalidSchema):
- requests.get('10.122.1.1:3128/')
- with pytest.raises(InvalidURL):
- requests.get('http://')
+ @pytest.mark.parametrize(
+ 'exception, url',
+ (
+ (MissingSchema, 'hiwpefhipowhefopw'),
+ (InvalidSchema, 'localhost:3128'),
+ (InvalidSchema, 'localhost.localdomain:3128/'),
+ (InvalidSchema, '10.122.1.1:3128/'),
+ (InvalidURL, 'http://'),
+ )
+ )
+ def test_invalid_url(self, exception, url):
+ with pytest.raises(exception):
+ requests.get(url)
def test_basic_building(self):
req = requests.Request()
@@ -118,11 +110,10 @@ class TestRequests(object):
assert pr.url == req.url
assert pr.body == 'life=42'
- def test_no_content_length(self, httpbin):
- get_req = requests.Request('GET', httpbin('get')).prepare()
- assert 'Content-Length' not in get_req.headers
- head_req = requests.Request('HEAD', httpbin('head')).prepare()
- assert 'Content-Length' not in head_req.headers
+ @pytest.mark.parametrize('method', ('GET', 'HEAD'))
+ def test_no_content_length(self, httpbin, method):
+ req = requests.Request(method, httpbin(method.lower())).prepare()
+ assert 'Content-Length' not in req.headers
def test_override_content_length(self, httpbin):
headers = {
@@ -137,13 +128,16 @@ class TestRequests(object):
assert request.path_url == '/get/test%20case'
- def test_params_are_added_before_fragment(self):
- request = requests.Request('GET',
- "http://example.com/path#fragment", params={"a": "b"}).prepare()
- assert request.url == "http://example.com/path?a=b#fragment"
- request = requests.Request('GET',
- "http://example.com/path?key=value#fragment", params={"a": "b"}).prepare()
- assert request.url == "http://example.com/path?key=value&a=b#fragment"
+ @pytest.mark.parametrize(
+ 'url, expected',
+ (
+ ('http://example.com/path#fragment', 'http://example.com/path?a=b#fragment'),
+ ('http://example.com/path?key=value#fragment', 'http://example.com/path?key=value&a=b#fragment')
+ )
+ )
+ def test_params_are_added_before_fragment(self, url, expected):
+ request = requests.Request('GET', url, params={"a": "b"}).prepare()
+ assert request.url == expected
def test_params_original_order_is_preserved_by_default(self):
param_ordered_dict = OrderedDict((('z', 1), ('a', 1), ('k', 1), ('d', 1)))
@@ -162,16 +156,15 @@ class TestRequests(object):
data=u"ööö".encode("utf-8")).prepare()
assert isinstance(request.body, bytes)
- def test_mixed_case_scheme_acceptable(self, httpbin):
+ @pytest.mark.parametrize('scheme', ('http://', 'HTTP://', 'hTTp://', 'HttP://'))
+ def test_mixed_case_scheme_acceptable(self, httpbin, scheme):
s = requests.Session()
s.proxies = getproxies()
parts = urlparse(httpbin('get'))
- schemes = ['http://', 'HTTP://', 'hTTp://', 'HttP://']
- for scheme in schemes:
- url = scheme + parts.netloc + parts.path
- r = requests.Request('GET', url)
- r = s.send(r.prepare())
- assert r.status_code == 200, 'failed for scheme {0}'.format(scheme)
+ url = scheme + parts.netloc + parts.path
+ r = requests.Request('GET', url)
+ r = s.send(r.prepare())
+ assert r.status_code == 200, 'failed for scheme {0}'.format(scheme)
def test_HTTP_200_OK_GET_ALTERNATIVE(self, httpbin):
r = requests.Request('GET', httpbin('get'))
@@ -323,21 +316,15 @@ class TestRequests(object):
prep = ses.prepare_request(req)
assert 'Accept-Encoding' not in prep.headers
- def test_user_agent_transfers(self, httpbin):
-
- heads = {
- 'User-agent': 'Mozilla/5.0 (github.com/kennethreitz/requests)'
- }
-
- r = requests.get(httpbin('user-agent'), headers=heads)
- assert heads['User-agent'] in r.text
+ @pytest.mark.parametrize('key', ('User-agent', 'user-agent'))
+ def test_user_agent_transfers(self, httpbin, key):
heads = {
- 'user-agent': 'Mozilla/5.0 (github.com/kennethreitz/requests)'
+ key: 'Mozilla/5.0 (github.com/kennethreitz/requests)'
}
r = requests.get(httpbin('user-agent'), headers=heads)
- assert heads['user-agent'] in r.text
+ assert heads[key] in r.text
def test_HTTP_200_OK_HEAD(self, httpbin):
r = requests.head(httpbin('get'))
@@ -362,20 +349,20 @@ class TestRequests(object):
r = s.get(url)
assert r.status_code == 200
- def test_connection_error_invalid_domain(self):
- """Connecting to an unknown domain should raise a ConnectionError"""
- with pytest.raises(ConnectionError):
- requests.get("http://doesnotexist.google.com")
-
- def test_connection_error_invalid_port(self):
- """Connecting to an invalid port should raise a ConnectionError"""
- with pytest.raises(ConnectionError):
- requests.get("http://localhost:1", timeout=1)
-
- def test_LocationParseError(self):
- """Inputing a URL that cannot be parsed should raise an InvalidURL error"""
- with pytest.raises(InvalidURL):
- requests.get("http://fe80::5054:ff:fe5a:fc0")
+ @pytest.mark.parametrize(
+ 'url, exception',
+ (
+ # Connecting to an unknown domain should raise a ConnectionError
+ ('http://doesnotexist.google.com', ConnectionError),
+ # Connecting to an invalid port should raise a ConnectionError
+ ('http://localhost:1', ConnectionError),
+ # Inputing a URL that cannot be parsed should raise an InvalidURL error
+ ('http://fe80::5054:ff:fe5a:fc0', InvalidURL)
+ )
+ )
+ def test_errors(self, url, exception):
+ with pytest.raises(exception):
+ requests.get(url, timeout=1)
def test_basicauth_with_netrc(self, httpbin):
auth = ('user', 'pass')
@@ -480,7 +467,7 @@ class TestRequests(object):
def test_POSTBIN_GET_POST_FILES(self, httpbin):
url = httpbin('post')
- post1 = requests.post(url).raise_for_status()
+ requests.post(url).raise_for_status()
post1 = requests.post(url, data={'some': 'data'})
assert post1.status_code == 200
@@ -498,7 +485,7 @@ class TestRequests(object):
def test_POSTBIN_GET_POST_FILES_WITH_DATA(self, httpbin):
url = httpbin('post')
- post1 = requests.post(url).raise_for_status()
+ requests.post(url).raise_for_status()
post1 = requests.post(url, data={'some': 'data'})
assert post1.status_code == 200
@@ -536,13 +523,18 @@ class TestRequests(object):
r = requests.get(httpbin('gzip'))
r.content.decode('ascii')
- def test_unicode_get(self, httpbin):
- url = httpbin('/get')
- requests.get(url, params={'foo': 'føø'})
- requests.get(url, params={'føø': 'føø'})
- requests.get(url, params={'føø': 'føø'})
- requests.get(url, params={'foo': 'foo'})
- requests.get(httpbin('ø'), params={'foo': 'foo'})
+ @pytest.mark.parametrize(
+ 'url, params',
+ (
+ ('/get', {'foo': 'føø'}),
+ ('/get', {'føø': 'føø'}),
+ ('/get', {'føø': 'føø'}),
+ ('/get', {'foo': 'foo'}),
+ ('ø', {'foo': 'foo'}),
+ )
+ )
+ def test_unicode_get(self, httpbin, url, params):
+ requests.get(httpbin(url), params=params)
def test_unicode_header_name(self, httpbin):
requests.put(
@@ -566,24 +558,17 @@ class TestRequests(object):
files={'file': ('test_requests.py', open(__file__, 'rb'))})
assert r.status_code == 200
- def test_unicode_multipart_post(self, httpbin):
- r = requests.post(httpbin('post'),
- data={'stuff': u('ëlïxr')},
- files={'file': ('test_requests.py', open(__file__, 'rb'))})
- assert r.status_code == 200
-
- r = requests.post(httpbin('post'),
- data={'stuff': u('ëlïxr').encode('utf-8')},
- files={'file': ('test_requests.py', open(__file__, 'rb'))})
- assert r.status_code == 200
-
- r = requests.post(httpbin('post'),
- data={'stuff': 'elixr'},
- files={'file': ('test_requests.py', open(__file__, 'rb'))})
- assert r.status_code == 200
-
+ @pytest.mark.parametrize(
+ 'data', (
+ {'stuff': u('ëlïxr')},
+ {'stuff': u('ëlïxr').encode('utf-8')},
+ {'stuff': 'elixr'},
+ {'stuff': 'elixr'.encode('utf-8')},
+ )
+ )
+ def test_unicode_multipart_post(self, httpbin, data):
r = requests.post(httpbin('post'),
- data={'stuff': 'elixr'.encode('utf-8')},
+ data=data,
files={'file': ('test_requests.py', open(__file__, 'rb'))})
assert r.status_code == 200
@@ -627,6 +612,7 @@ class TestRequests(object):
def test_hook_receives_request_arguments(self, httpbin):
def hook(resp, **kwargs):
+ # FIXME. Not executed
assert resp is not None
assert kwargs != {}
@@ -1118,7 +1104,7 @@ class TestRequests(object):
i = 0
for item in r.history:
assert item.history == total[0:i]
- i = i + 1
+ i += 1
def test_json_param_post_content_type_works(self, httpbin):
r = requests.post(
@@ -1163,36 +1149,25 @@ class TestRequests(object):
assert len(list(r.iter_lines())) == 3
-class TestContentEncodingDetection(unittest.TestCase):
+class TestContentEncodingDetection:
def test_none(self):
encodings = requests.utils.get_encodings_from_content('')
assert not len(encodings)
- def test_html_charset(self):
- """HTML5 meta charset attribute"""
- content = '<meta charset="UTF-8">'
- encodings = requests.utils.get_encodings_from_content(content)
- assert len(encodings) == 1
- assert encodings[0] == 'UTF-8'
-
- def test_html4_pragma(self):
- """HTML4 pragma directive"""
- content = '<meta http-equiv="Content-type" content="text/html;charset=UTF-8">'
- encodings = requests.utils.get_encodings_from_content(content)
- assert len(encodings) == 1
- assert encodings[0] == 'UTF-8'
-
- def test_xhtml_pragma(self):
- """XHTML 1.x served with text/html MIME type"""
- content = '<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />'
- encodings = requests.utils.get_encodings_from_content(content)
- assert len(encodings) == 1
- assert encodings[0] == 'UTF-8'
-
- def test_xml(self):
- """XHTML 1.x served as XML"""
- content = '<?xml version="1.0" encoding="UTF-8"?>'
+ @pytest.mark.parametrize(
+ 'content', (
+ # HTML5 meta charset attribute
+ '<meta charset="UTF-8">',
+ # HTML4 pragma directive
+ '<meta http-equiv="Content-type" content="text/html;charset=UTF-8">',
+ # XHTML 1.x served with text/html MIME type
+ '<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />',
+ # XHTML 1.x served as XML
+ '<?xml version="1.0" encoding="UTF-8"?>',
+ )
+ )
+ def test_pragmas(self, content):
encodings = requests.utils.get_encodings_from_content(content)
assert len(encodings) == 1
assert encodings[0] == 'UTF-8'
@@ -1207,22 +1182,17 @@ class TestContentEncodingDetection(unittest.TestCase):
assert encodings == ['HTML5', 'HTML4', 'XML']
-class TestCaseInsensitiveDict(unittest.TestCase):
+class TestCaseInsensitiveDict:
- def test_mapping_init(self):
- cid = CaseInsensitiveDict({'Foo': 'foo', 'BAr': 'bar'})
- assert len(cid) == 2
- assert 'foo' in cid
- assert 'bar' in cid
-
- def test_iterable_init(self):
- cid = CaseInsensitiveDict([('Foo', 'foo'), ('BAr', 'bar')])
- assert len(cid) == 2
- assert 'foo' in cid
- assert 'bar' in cid
-
- def test_kwargs_init(self):
- cid = CaseInsensitiveDict(FOO='foo', BAr='bar')
+ @pytest.mark.parametrize(
+ 'cid',
+ (
+ CaseInsensitiveDict({'Foo': 'foo', 'BAr': 'bar'}),
+ CaseInsensitiveDict([('Foo', 'foo'), ('BAr', 'bar')]),
+ CaseInsensitiveDict(FOO='foo', BAr='bar'),
+ )
+ )
+ def test_init(self, cid):
assert len(cid) == 2
assert 'foo' in cid
assert 'bar' in cid
@@ -1356,7 +1326,7 @@ class TestCaseInsensitiveDict(unittest.TestCase):
assert cid != cid_copy
-class UtilsTestCase(unittest.TestCase):
+class TestUtils:
def test_super_len_io_streams(self):
""" Ensures that we properly deal with different kinds of IO streams. """
@@ -1467,7 +1437,7 @@ class UtilsTestCase(unittest.TestCase):
def test_get_auth_from_url(self):
"""Ensures that username and password in well-encoded URI as per
- RFC 3986 are correclty extracted."""
+ RFC 3986 are correctly extracted."""
from requests.utils import get_auth_from_url
from requests.compat import quote
percent_encoding_test_chars = "%!*'();:@&=+$,/?#[] "
@@ -1496,7 +1466,7 @@ class UtilsTestCase(unittest.TestCase):
assert quoted == requote_uri(quoted)
-class TestMorselToCookieExpires(unittest.TestCase):
+class TestMorselToCookieExpires:
"""Tests for morsel_to_cookie when morsel contains expires."""
@@ -1508,20 +1478,18 @@ class TestMorselToCookieExpires(unittest.TestCase):
cookie = morsel_to_cookie(morsel)
assert cookie.expires == 1
- def test_expires_invalid_int(self):
+ @pytest.mark.parametrize(
+ 'value, exception',
+ (
+ (100, TypeError),
+ ('woops', ValueError),
+ )
+ )
+ def test_expires_invalid_int(self, value, exception):
"""Test case where an invalid type is passed for expires."""
-
morsel = Morsel()
- morsel['expires'] = 100
- with pytest.raises(TypeError):
- morsel_to_cookie(morsel)
-
- def test_expires_invalid_str(self):
- """Test case where an invalid string is input."""
-
- morsel = Morsel()
- morsel['expires'] = 'woops'
- with pytest.raises(ValueError):
+ morsel['expires'] = value
+ with pytest.raises(exception):
morsel_to_cookie(morsel)
def test_expires_none(self):
@@ -1533,7 +1501,7 @@ class TestMorselToCookieExpires(unittest.TestCase):
assert cookie.expires is None
-class TestMorselToCookieMaxAge(unittest.TestCase):
+class TestMorselToCookieMaxAge:
"""Tests for morsel_to_cookie when morsel contains max-age."""
@@ -1585,14 +1553,14 @@ class TestTimeout:
def test_read_timeout(self, httpbin):
try:
requests.get(httpbin('delay/10'), timeout=(None, 0.1))
- assert False, "The recv() request should time out."
+ pytest.fail('The recv() request should time out.')
except ReadTimeout:
pass
def test_connect_timeout(self):
try:
requests.get(TARPIT, timeout=(0.1, None))
- assert False, "The connect() request should time out."
+ pytest.fail('The connect() request should time out.')
except ConnectTimeout as e:
assert isinstance(e, ConnectionError)
assert isinstance(e, Timeout)
@@ -1600,7 +1568,7 @@ class TestTimeout:
def test_total_timeout_connect(self):
try:
requests.get(TARPIT, timeout=(0.1, 0.1))
- assert False, "The connect() request should time out."
+ pytest.fail('The connect() request should time out.')
except ConnectTimeout:
pass
@@ -1669,7 +1637,6 @@ class TestRedirects:
assert session.calls[-1] == send_call
-
@pytest.fixture
def list_of_tuples():
return [
@@ -1764,7 +1731,3 @@ def test_vendor_aliases():
with pytest.raises(ImportError):
from requests.packages import webbrowser
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/tox.ini b/tox.ini
new file mode 100644
index 00000000..a45f298c
--- /dev/null
+++ b/tox.ini
@@ -0,0 +1,8 @@
+[tox]
+envlist = py26, py27, py33, py34, py35, pypy
+
+[testenv]
+setenv =
+ PYTHONPATH = {toxinidir}:{toxinidir}/requests
+whitelist_externals = make
+commands = make test \ No newline at end of file