Hello community,
here is the log from the commit of package python-requests-mock for openSUSE:Factory checked in at 2016-09-30 15:33:48
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-requests-mock (Old)
and /work/SRC/openSUSE:Factory/.python-requests-mock.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-requests-mock"
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-requests-mock/python-requests-mock.changes 2016-07-14 09:46:29.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.python-requests-mock.new/python-requests-mock.changes 2016-09-30 15:33:49.000000000 +0200
@@ -1,0 +2,11 @@
+Wed Sep 28 09:00:13 UTC 2016 - tbechtold@suse.com
+
+- update to 1.1.0:
+ * Add a called_once property to adapter
+ * Enable case sensitive matching
+ * Provide fixture extras for pip
+ * Allow doing real_http per mock via the mocker
+ * Return b'' when reading closed response
+ * Fixture documentation error
+
+-------------------------------------------------------------------
Old:
----
requests-mock-1.0.0.tar.gz
New:
----
requests-mock-1.1.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-requests-mock.spec ++++++
--- /var/tmp/diff_new_pack.8ipqaQ/_old 2016-09-30 15:33:52.000000000 +0200
+++ /var/tmp/diff_new_pack.8ipqaQ/_new 2016-09-30 15:33:52.000000000 +0200
@@ -17,7 +17,7 @@
Name: python-requests-mock
-Version: 1.0.0
+Version: 1.1.0
Release: 0
Summary: Mock out responses from the requests package
License: Apache-2.0
++++++ requests-mock-1.0.0.tar.gz -> requests-mock-1.1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requests-mock-1.0.0/AUTHORS new/requests-mock-1.1.0/AUTHORS
--- old/requests-mock-1.0.0/AUTHORS 2016-05-09 07:14:35.000000000 +0200
+++ new/requests-mock-1.1.0/AUTHORS 2016-09-14 09:07:03.000000000 +0200
@@ -4,5 +4,7 @@
Janonymous
Jeremy Stanley
Louis Taylor
+Manuel Kaufmann
Monty Taylor
Sebastian Kalinowski
+reedip
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requests-mock-1.0.0/ChangeLog new/requests-mock-1.1.0/ChangeLog
--- old/requests-mock-1.0.0/ChangeLog 2016-05-09 07:14:35.000000000 +0200
+++ new/requests-mock-1.1.0/ChangeLog 2016-09-14 09:07:03.000000000 +0200
@@ -1,6 +1,16 @@
CHANGES
=======
+1.1.0
+-----
+
+* Add a called_once property to adapter
+* Enable case sensitive matching
+* Provide fixture extras for pip
+* Allow doing real_http per mock via the mocker
+* Return b'' when reading closed response
+* Fixture documentation error
+
1.0.0
-----
@@ -9,6 +19,7 @@
* Doc fixups
* Expose cert and proxies as attributes of the last request
* Add timeout and allow_retries to RequestProxy
+* Add trove support for py34 and remove py33
* Fix py34 DB issue and remove py33/py26
* Remove pypip.in badge from readme
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requests-mock-1.0.0/PKG-INFO new/requests-mock-1.1.0/PKG-INFO
--- old/requests-mock-1.0.0/PKG-INFO 2016-05-09 07:14:35.000000000 +0200
+++ new/requests-mock-1.1.0/PKG-INFO 2016-09-14 09:07:03.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: requests-mock
-Version: 1.0.0
+Version: 1.1.0
Summary: Mock out responses from the requests package
Home-page: https://requests-mock.readthedocs.org/
Author: Jamie Lennox
@@ -105,5 +105,5 @@
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
Classifier: Topic :: Software Development :: Testing
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requests-mock-1.0.0/docs/fixture.rst new/requests-mock-1.1.0/docs/fixture.rst
--- old/requests-mock-1.0.0/docs/fixture.rst 2016-05-09 07:12:34.000000000 +0200
+++ new/requests-mock-1.1.0/docs/fixture.rst 2016-09-14 09:05:03.000000000 +0200
@@ -4,8 +4,12 @@
`Fixtures`_ provide a way to create reusable state and helper methods in test cases.
-To use the *requests-mock* fixture your tests need to have a dependency on the `fixtures`_ library and the `mock`_ library.
-These are not provided by *requests-mock*.
+To use the *requests-mock* fixture your tests need to have a dependency on the `fixtures`_ library.
+This can be optionally installed when you install *requests-mock* by doing:
+
+.. code:: shell
+
+ pip install requests-mock[fixture]
The fixture mocks the :py:meth:`requests.Session.get_adapter` method so that all requests will be served by the mock adapter.
@@ -23,7 +27,7 @@
...
... def setUp(self):
... super(MyTestCase, self).setUp()
- ... self.requests_mock = self.useFixture(requests_mock.Mock())
+ ... self.requests_mock = self.useFixture(fixture.Fixture())
... self.requests_mock.register_uri('GET', self.TEST_URL, text='respA')
...
... def test_method(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requests-mock-1.0.0/docs/index.rst new/requests-mock-1.1.0/docs/index.rst
--- old/requests-mock-1.0.0/docs/index.rst 2016-05-09 07:12:34.000000000 +0200
+++ new/requests-mock-1.1.0/docs/index.rst 2016-09-14 09:05:03.000000000 +0200
@@ -11,6 +11,7 @@
mocker
matching
response
+ knownissues
history
adapter
contrib
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requests-mock-1.0.0/docs/knownissues.rst new/requests-mock-1.1.0/docs/knownissues.rst
--- old/requests-mock-1.0.0/docs/knownissues.rst 1970-01-01 01:00:00.000000000 +0100
+++ new/requests-mock-1.1.0/docs/knownissues.rst 2016-09-14 09:05:03.000000000 +0200
@@ -0,0 +1,34 @@
+============
+Known Issues
+============
+
+.. _case_insensitive:
+
+Case Insensitivity
+------------------
+
+By default matching is done in a completely case insensitive way. This makes
+sense for the protocol and host components which are defined as insensitive by
+RFCs however it does not make sense for path.
+
+A byproduct of this is that when using request history the values for path, qs
+etc are all lowercased as this was what was used to do the matching.
+
+To work around this when building an Adapter or Mocker you do
+
+.. code:: python
+
+ with requests_mock.mock(case_sensitive=True) as m:
+ ...
+
+or you can override the default globally by
+
+.. code:: python
+
+ requests_mock.mock.case_sensitive = True
+
+It is recommended to run the global fix as it is intended that case sensitivity
+will become the default in future releases.
+
+Note that even with case_sensitive enabled the protocol and netloc of a mock
+are still matched in a case insensitive way.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requests-mock-1.0.0/docs/matching.rst new/requests-mock-1.1.0/docs/matching.rst
--- old/requests-mock-1.0.0/docs/matching.rst 2016-05-09 07:12:34.000000000 +0200
+++ new/requests-mock-1.1.0/docs/matching.rst 2016-09-14 09:05:03.000000000 +0200
@@ -38,6 +38,18 @@
>>> session = requests.Session()
>>> session.mount('mock', adapter)
+.. note::
+
+ By default all matching is case insensitive. This can be adjusted by
+ passing case_sensitive=True when creating a mocker or adapter or globally
+ by doing:
+
+ .. code:: python
+
+ requests_mock.mock.case_sensitive = True
+
+ for more see: :ref:`case_insensitive`
+
Simple
======
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requests-mock-1.0.0/docs/mocker.rst new/requests-mock-1.1.0/docs/mocker.rst
--- old/requests-mock-1.0.0/docs/mocker.rst 2016-05-09 07:12:34.000000000 +0200
+++ new/requests-mock-1.1.0/docs/mocker.rst 2016-09-14 09:05:03.000000000 +0200
@@ -132,3 +132,18 @@
...
'resp'
200
+
+*New in 1.1*
+
+Similarly when using a mocker you can register an individual URI to bypass the mocking infrastructure and make a real request. Note this only works when using the mocker and not when directly mounting an adapter.
+
+.. doctest::
+
+ >>> with requests_mock.Mocker() as m:
+ ... m.register_uri('GET', 'http://test.com', text='resp')
+ ... m.register_uri('GET', 'http://www.google.com', real_http=True)
+ ... print(requests.get('http://test.com').text)
+ ... print(requests.get('http://www.google.com').status_code) # doctest: +SKIP
+ ...
+ 'resp'
+ 200
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requests-mock-1.0.0/releasenotes/notes/Add-called_once-property-a69546448cbd5542.yaml new/requests-mock-1.1.0/releasenotes/notes/Add-called_once-property-a69546448cbd5542.yaml
--- old/requests-mock-1.0.0/releasenotes/notes/Add-called_once-property-a69546448cbd5542.yaml 1970-01-01 01:00:00.000000000 +0100
+++ new/requests-mock-1.1.0/releasenotes/notes/Add-called_once-property-a69546448cbd5542.yaml 2016-09-14 09:05:03.000000000 +0200
@@ -0,0 +1,6 @@
+---
+prelude: >
+ Add a called_once property to the mockers.
+features:
+ - A called_once property was added to the adapter and the mocker. This gives
+ us an easy way to emulate mock's assert_called_once.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requests-mock-1.0.0/releasenotes/notes/case-insensitive-matching-a3143221359bbf2d.yaml new/requests-mock-1.1.0/releasenotes/notes/case-insensitive-matching-a3143221359bbf2d.yaml
--- old/requests-mock-1.0.0/releasenotes/notes/case-insensitive-matching-a3143221359bbf2d.yaml 1970-01-01 01:00:00.000000000 +0100
+++ new/requests-mock-1.1.0/releasenotes/notes/case-insensitive-matching-a3143221359bbf2d.yaml 2016-09-14 09:05:03.000000000 +0200
@@ -0,0 +1,17 @@
+---
+prelude: >
+ It is now possible to make URL matching and request history not lowercase
+ the provided URLs.
+features:
+ - You can pass case_sensitive=True to an adapter or set
+ `requests_mock.mock.case_sensitive = True` globally to enable case
+ sensitive matching.
+upgrade:
+ - It is recommended you add `requests_mock.mock.case_sensitive = True` to
+ your base test file to globally turn on case sensitive matching as this
+ will become the default in a 2.X release.
+fixes:
+ - Reported in bug \#1584008 all request matching is done in a case
+ insensitive way, as a byproduct of this request history is handled in a
+ case insensitive way. This can now be controlled by setting case_sensitive
+ to True when creating an adapter or globally.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requests-mock-1.0.0/releasenotes/notes/fixture-extras-699a5b5fb5bd6aab.yaml new/requests-mock-1.1.0/releasenotes/notes/fixture-extras-699a5b5fb5bd6aab.yaml
--- old/requests-mock-1.0.0/releasenotes/notes/fixture-extras-699a5b5fb5bd6aab.yaml 1970-01-01 01:00:00.000000000 +0100
+++ new/requests-mock-1.1.0/releasenotes/notes/fixture-extras-699a5b5fb5bd6aab.yaml 2016-09-14 09:05:03.000000000 +0200
@@ -0,0 +1,7 @@
+---
+prelude: >
+ Installing the requirements for the 'fixture' contrib package can now be
+ done via pip with `pip install requests-mock[fixture]`
+features:
+ Added 'fixture' to pip extras so you can install the fixture requirements
+ with `pip install requests-mock[fixture]`
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requests-mock-1.0.0/requests_mock/adapter.py new/requests-mock-1.1.0/requests_mock/adapter.py
--- old/requests-mock-1.0.0/requests_mock/adapter.py 2016-05-09 07:12:37.000000000 +0200
+++ new/requests-mock-1.1.0/requests_mock/adapter.py 2016-09-14 09:05:03.000000000 +0200
@@ -46,13 +46,22 @@
self._cert = kwargs.pop('cert', None)
self._proxies = copy.deepcopy(kwargs.pop('proxies', {}))
+ # FIXME(jamielennox): This is part of bug #1584008 and should default
+ # to True (or simply removed) in a major version bump.
+ self._case_sensitive = kwargs.pop('case_sensitive', False)
+
def __getattr__(self, name):
return getattr(self._request, name)
@property
def _url_parts(self):
if self._url_parts_ is None:
- self._url_parts_ = urlparse.urlparse(self._request.url.lower())
+ url = self._request.url
+
+ if not self._case_sensitive:
+ url = url.lower()
+
+ self._url_parts_ = urlparse.urlparse(url)
return self._url_parts_
@@ -147,14 +156,29 @@
return self.call_count > 0
@property
+ def called_once(self):
+ return self.call_count == 1
+
+ @property
def call_count(self):
return len(self.request_history)
+class _RunRealHTTP(Exception):
+ """A fake exception to jump out of mocking and allow a real request.
+
+ This exception is caught at the mocker level and allows it to execute this
+ request through the real requests mechanism rather than the mocker.
+
+ It should never be exposed to a user.
+ """
+
+
class _Matcher(_RequestHistoryTracker):
"""Contains all the information about a provided URL to match."""
- def __init__(self, method, url, responses, complete_qs, request_headers):
+ def __init__(self, method, url, responses, complete_qs, request_headers,
+ real_http, case_sensitive):
"""
:param bool complete_qs: Match the entire query string. By default URLs
match if all the provided matcher query arguments are matched and
@@ -162,15 +186,31 @@
require that the entire query string needs to match.
"""
super(_Matcher, self).__init__()
+
self._method = method
self._url = url
- try:
- self._url_parts = urlparse.urlparse(url.lower())
- except:
- self._url_parts = None
self._responses = responses
self._complete_qs = complete_qs
self._request_headers = request_headers
+ self._real_http = real_http
+
+ # url can be a regex object or ANY so don't always run urlparse
+ if isinstance(url, six.string_types):
+ url_parts = urlparse.urlparse(url)
+ self._scheme = url_parts.scheme.lower()
+ self._netloc = url_parts.netloc.lower()
+ self._path = url_parts.path or '/'
+ self._query = url_parts.query
+
+ if not case_sensitive:
+ self._path = self._path.lower()
+ self._query = self._query.lower()
+
+ else:
+ self._scheme = None
+ self._netloc = None
+ self._path = None
+ self._query = None
def _match_method(self, request):
if self._method is ANY:
@@ -189,18 +229,20 @@
if hasattr(self._url, 'search'):
return self._url.search(request.url) is not None
- if self._url_parts.scheme and request.scheme != self._url_parts.scheme:
+ # scheme is always matched case insensitive
+ if self._scheme and request.scheme.lower() != self._scheme:
return False
- if self._url_parts.netloc and request.netloc != self._url_parts.netloc:
+ # netloc is always matched case insensitive
+ if self._netloc and request.netloc.lower() != self._netloc:
return False
- if (request.path or '/') != (self._url_parts.path or '/'):
+ if (request.path or '/') != self._path:
return False
# construct our own qs structure as we remove items from it below
request_qs = urlparse.parse_qs(request.query)
- matcher_qs = urlparse.parse_qs(self._url_parts.query)
+ matcher_qs = urlparse.parse_qs(self._query)
for k, vals in six.iteritems(matcher_qs):
for v in vals:
@@ -248,6 +290,11 @@
if not self._match(request):
return None
+ # doing this before _add_to_history means real requests are not stored
+ # in the request history. I'm not sure what is better here.
+ if self._real_http:
+ raise _RunRealHTTP()
+
if len(self._responses) > 1:
response_matcher = self._responses.pop(0)
else:
@@ -261,12 +308,15 @@
"""A fake adapter than can return predefined responses.
"""
- def __init__(self):
+ def __init__(self, case_sensitive=False):
super(Adapter, self).__init__()
+ self._case_sensitive = case_sensitive
self._matchers = []
def send(self, request, **kwargs):
- request = _RequestObjectProxy(request, **kwargs)
+ request = _RequestObjectProxy(request,
+ case_sensitive=self._case_sensitive,
+ **kwargs)
self._add_to_history(request)
for matcher in reversed(self._matchers):
@@ -294,19 +344,31 @@
"""
complete_qs = kwargs.pop('complete_qs', False)
request_headers = kwargs.pop('request_headers', {})
+ real_http = kwargs.pop('_real_http', False)
if response_list and kwargs:
raise RuntimeError('You should specify either a list of '
'responses OR response kwargs. Not both.')
+ elif real_http and (response_list or kwargs):
+ raise RuntimeError('You should specify either response data '
+ 'OR real_http. Not both.')
elif not response_list:
- response_list = [kwargs]
+ response_list = [] if real_http else [kwargs]
+ # NOTE(jamielennox): case_sensitive is not present as a kwarg because i
+ # think there would be an edge case where the adapter and register_uri
+ # had different values.
+ # Ideally case_sensitive would be a value passed to match() however
+ # this would change the contract of matchers so we pass ito to the
+ # proxy and the matcher seperately.
responses = [response._MatcherResponse(**k) for k in response_list]
matcher = _Matcher(method,
url,
responses,
+ case_sensitive=self._case_sensitive,
complete_qs=complete_qs,
- request_headers=request_headers)
+ request_headers=request_headers,
+ real_http=real_http)
self.add_matcher(matcher)
return matcher
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requests-mock-1.0.0/requests_mock/mocker.py new/requests-mock-1.1.0/requests_mock/mocker.py
--- old/requests-mock-1.0.0/requests_mock/mocker.py 2016-05-09 07:12:34.000000000 +0200
+++ new/requests-mock-1.1.0/requests_mock/mocker.py 2016-09-14 09:05:03.000000000 +0200
@@ -34,14 +34,33 @@
"""
_PROXY_FUNCS = set(['last_request',
- 'register_uri',
'add_matcher',
'request_history',
'called',
'call_count'])
+ case_sensitive = False
+ """case_sensitive handles a backwards incompatible bug. The URL used to
+ match against our matches and that is saved in request_history is always
+ lowercased. This is incorrect as it reports incorrect history to the user
+ and doesn't allow case sensitive path matching.
+
+ Unfortunately fixing this change is backwards incompatible in the 1.X
+ series as people may rely on this behaviour. To work around this you can
+ globally set:
+
+ requests_mock.mock.case_sensitive = True
+
+ which will prevent the lowercase being executed and return case sensitive
+ url and query information.
+
+ This will become the default in a 2.X release. See bug: #1584008.
+ """
+
def __init__(self, **kwargs):
- self._adapter = adapter.Adapter()
+ case_sensitive = kwargs.pop('case_sensitive', self.case_sensitive)
+ self._adapter = adapter.Adapter(case_sensitive=case_sensitive)
+
self._real_http = kwargs.pop('real_http', False)
self._real_send = None
@@ -70,6 +89,10 @@
except exceptions.NoMockAddress:
if not self._real_http:
raise
+ except adapter._RunRealHTTP:
+ # this mocker wants you to run the request through the real
+ # requests library rather than the mocking. Let it.
+ pass
finally:
requests.Session.get_adapter = real_get_adapter
@@ -95,6 +118,12 @@
raise AttributeError(name)
+ def register_uri(self, *args, **kwargs):
+ # you can pass real_http here, but it's private to pass direct to the
+ # adapter, because if you pass direct to the adapter you'll see the exc
+ kwargs['_real_http'] = kwargs.pop('real_http', False)
+ return self._adapter.register_uri(*args, **kwargs)
+
def request(self, *args, **kwargs):
return self.register_uri(*args, **kwargs)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requests-mock-1.0.0/requests_mock/response.py new/requests-mock-1.1.0/requests_mock/response.py
--- old/requests-mock-1.0.0/requests_mock/response.py 2016-05-09 07:12:34.000000000 +0200
+++ new/requests-mock-1.1.0/requests_mock/response.py 2016-09-14 09:05:03.000000000 +0200
@@ -103,6 +103,22 @@
merge_cookies(response.cookies, cookies)
+class _IOReader(six.BytesIO):
+ """A reader that makes a BytesIO look like a HTTPResponse.
+
+ A HTTPResponse will return an empty string when you read from it after
+ the socket has been closed. A BytesIO will raise a ValueError. For
+ compatibility we want to do the same thing a HTTPResponse does.
+ """
+
+ def read(self, *args, **kwargs):
+ if self.closed:
+ return six.b('')
+
+ # not a new style object in python 2
+ return six.BytesIO.read(self, *args, **kwargs)
+
+
def create_response(request, **kwargs):
"""
:param int status_code: The status code to return upon a successful
@@ -142,12 +158,12 @@
encoding = 'utf-8'
content = text.encode(encoding)
if content is not None:
- body = six.BytesIO(content)
+ body = _IOReader(content)
if not raw:
raw = HTTPResponse(status=kwargs.get('status_code', _DEFAULT_STATUS),
headers=kwargs.get('headers', {}),
reason=kwargs.get('reason'),
- body=body or six.BytesIO(six.b('')),
+ body=body or _IOReader(six.b('')),
decode_content=False,
preload_content=False,
original_response=compat._fake_http_response)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requests-mock-1.0.0/requests_mock/tests/test_adapter.py new/requests-mock-1.1.0/requests_mock/tests/test_adapter.py
--- old/requests-mock-1.0.0/requests_mock/tests/test_adapter.py 2016-05-09 07:12:37.000000000 +0200
+++ new/requests-mock-1.1.0/requests_mock/tests/test_adapter.py 2016-09-14 09:05:03.000000000 +0200
@@ -334,9 +334,11 @@
m = self.adapter.register_uri('GET', self.url, text='resp')
self.assertEqual(0, m.call_count)
self.assertFalse(m.called)
+ self.assertFalse(m.called_once)
self.assertEqual(0, self.adapter.call_count)
self.assertFalse(self.adapter.called)
+ self.assertFalse(m.called_once)
def test_called_and_called_count(self):
m = self.adapter.register_uri('GET', self.url, text='resp')
@@ -349,9 +351,11 @@
self.assertEqual(len(resps), m.call_count)
self.assertTrue(m.called)
+ self.assertFalse(m.called_once)
self.assertEqual(len(resps), self.adapter.call_count)
self.assertTrue(self.adapter.called)
+ self.assertFalse(m.called_once)
def test_adapter_picks_correct_adatper(self):
good = '%s://test3.url/' % self.PREFIX
@@ -436,6 +440,7 @@
resp = self.session.post(self.url, data=data)
self.assertEqual(1, m.call_count)
+ self.assertTrue(m.called_once)
self.assertEqual(dict_resp, resp.json())
def test_raises_exception(self):
@@ -445,6 +450,7 @@
self.session.get,
self.url)
+ self.assertTrue(self.adapter.called_once)
self.assertEqual(self.url, self.adapter.last_request.url)
def test_raises_exception_with_body_args_fails(self):
@@ -472,6 +478,7 @@
self.assertEqual(text2, resp2.text)
self.assertEqual(2, self.adapter.call_count)
+ self.assertFalse(self.adapter.called_once)
self.assertEqual(url1, self.adapter.request_history[0].url)
self.assertEqual(url2, self.adapter.request_history[1].url)
@@ -664,3 +671,53 @@
self.assertEqual(data, resp.text)
self.assertEqual(proxies, self.adapter.last_request.proxies)
self.assertIsNot(proxies, self.adapter.last_request.proxies)
+
+ def test_reading_closed_fp(self):
+ self.adapter.register_uri('GET', self.url, text='abc')
+ resp = self.session.get(self.url)
+
+ # raw will have been closed during the request reading
+ self.assertTrue(resp.raw.closed)
+
+ data = resp.raw.read()
+
+ self.assertIsInstance(data, six.binary_type)
+ self.assertEqual(0, len(data))
+
+ def test_case_sensitive_headers(self):
+ data = 'testdata'
+ headers = {'aBcDe': 'FgHiJ'}
+
+ self.adapter.register_uri('GET', self.url, text=data)
+ resp = self.session.get(self.url, headers=headers)
+
+ self.assertEqual('GET', self.adapter.last_request.method)
+ self.assertEqual(200, resp.status_code)
+ self.assertEqual(data, resp.text)
+
+ for k, v in headers.items():
+ self.assertEqual(v, self.adapter.last_request.headers[k])
+
+ def test_case_sensitive_history(self):
+ self.adapter._case_sensitive = True
+
+ data = 'testdata'
+ netloc = 'examPlE.CoM'
+ path = '/TesTER'
+ query = 'aBC=deF'
+
+ mock_url = '%s://%s%s' % (self.PREFIX, netloc.lower(), path)
+ request_url = '%s://%s%s?%s' % (self.PREFIX, netloc, path, query)
+
+ # test that the netloc is ignored when actually making the request
+ self.adapter.register_uri('GET', mock_url, text=data)
+ resp = self.session.get(request_url)
+
+ self.assertEqual('GET', self.adapter.last_request.method)
+ self.assertEqual(200, resp.status_code)
+ self.assertEqual(data, resp.text)
+
+ # but even still the mixed case parameters come out in history
+ self.assertEqual(netloc, self.adapter.last_request.netloc)
+ self.assertEqual(path, self.adapter.last_request.path)
+ self.assertEqual(query, self.adapter.last_request.query)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requests-mock-1.0.0/requests_mock/tests/test_matcher.py new/requests-mock-1.1.0/requests_mock/tests/test_matcher.py
--- old/requests-mock-1.0.0/requests_mock/tests/test_matcher.py 2016-05-09 07:12:34.000000000 +0200
+++ new/requests-mock-1.1.0/requests_mock/tests/test_matcher.py 2016-09-14 09:05:03.000000000 +0200
@@ -27,12 +27,16 @@
request_method='GET',
complete_qs=False,
headers=None,
- request_headers={}):
+ request_headers={},
+ real_http=False,
+ case_sensitive=False):
matcher = adapter._Matcher(matcher_method,
target,
[],
complete_qs,
- request_headers)
+ request_headers,
+ real_http=real_http,
+ case_sensitive=case_sensitive)
request = adapter._RequestObjectProxy._create(request_method,
url,
headers)
@@ -220,3 +224,44 @@
'http://www.test.com/path',
headers={'A': 'abc', 'b': 'def'},
request_headers={'c': 'ghi'})
+
+ # headers should be key insensitive and value sensitive, we have no
+ # choice here because they go into an insensitive dict.
+ self.assertMatch('/path',
+ 'http://www.test.com/path',
+ headers={'aBc': 'abc', 'DEF': 'def'},
+ request_headers={'abC': 'abc'})
+
+ self.assertNoMatch('/path',
+ 'http://www.test.com/path',
+ headers={'abc': 'aBC', 'DEF': 'def'},
+ request_headers={'abc': 'Abc'})
+
+ def test_case_sensitive_ignored_for_netloc_and_protocol(self):
+ for case_sensitive in (True, False):
+ self.assertMatch('http://AbC.CoM',
+ 'http://aBc.CoM',
+ case_sensitive=case_sensitive)
+
+ self.assertMatch('htTP://abc.com',
+ 'hTTp://abc.com',
+ case_sensitive=case_sensitive)
+
+ self.assertMatch('htTP://aBC.cOm',
+ 'hTTp://AbC.Com',
+ case_sensitive=case_sensitive)
+
+ def assertSensitiveMatch(self, target, url, **kwargs):
+ self.assertMatch(target, url, case_sensitive=False, **kwargs)
+ self.assertNoMatch(target, url, case_sensitive=True, **kwargs)
+
+ def test_case_sensitive_paths(self):
+ self.assertSensitiveMatch('http://abc.com/pAtH', 'http://abc.com/path')
+ self.assertSensitiveMatch('/pAtH', 'http://abc.com/path')
+
+ def test_case_sensitive_query(self):
+ self.assertSensitiveMatch('http://abc.com/path?abCD=efGH',
+ 'http://abc.com/path?abCd=eFGH')
+
+ self.assertSensitiveMatch('http://abc.com/path?abcd=efGH',
+ 'http://abc.com/path?abcd=eFGH')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requests-mock-1.0.0/requests_mock/tests/test_mocker.py new/requests-mock-1.1.0/requests_mock/tests/test_mocker.py
--- old/requests-mock-1.0.0/requests_mock/tests/test_mocker.py 2016-05-09 07:12:34.000000000 +0200
+++ new/requests-mock-1.1.0/requests_mock/tests/test_mocker.py 2016-09-14 09:05:03.000000000 +0200
@@ -15,6 +15,7 @@
import requests_mock
from requests_mock import compat
+from requests_mock import exceptions
from requests_mock.tests import base
original_send = requests.Session.send
@@ -173,6 +174,7 @@
self.assertEqual(1, m.call_count)
self.assertTrue(matcher.called)
+ self.assertTrue(matcher.called_once)
self.assertTrue(m.called)
self.assertEqual(m.request_history, matcher.request_history)
@@ -201,45 +203,119 @@
resp = requests.request(method, self.URL)
self.assertResponse(resp)
self.assertTrue(mock_obj.called)
+ self.assertTrue(mock_obj.called_once)
@requests_mock.Mocker()
def test_mocker_get(self, m):
mock_obj = m.get(self.URL, text=self.TEXT)
self.assertResponse(requests.get(self.URL))
self.assertTrue(mock_obj.called)
+ self.assertTrue(mock_obj.called_once)
@requests_mock.Mocker()
def test_mocker_options(self, m):
mock_obj = m.options(self.URL, text=self.TEXT)
self.assertResponse(requests.options(self.URL))
self.assertTrue(mock_obj.called)
+ self.assertTrue(mock_obj.called_once)
@requests_mock.Mocker()
def test_mocker_head(self, m):
mock_obj = m.head(self.URL, text=self.TEXT)
self.assertResponse(requests.head(self.URL))
self.assertTrue(mock_obj.called)
+ self.assertTrue(mock_obj.called_once)
@requests_mock.Mocker()
def test_mocker_post(self, m):
mock_obj = m.post(self.URL, text=self.TEXT)
self.assertResponse(requests.post(self.URL))
self.assertTrue(mock_obj.called)
+ self.assertTrue(mock_obj.called_once)
@requests_mock.Mocker()
def test_mocker_put(self, m):
mock_obj = m.put(self.URL, text=self.TEXT)
self.assertResponse(requests.put(self.URL))
self.assertTrue(mock_obj.called)
+ self.assertTrue(mock_obj.called_once)
@requests_mock.Mocker()
def test_mocker_patch(self, m):
mock_obj = m.patch(self.URL, text=self.TEXT)
self.assertResponse(requests.patch(self.URL))
self.assertTrue(mock_obj.called)
+ self.assertTrue(mock_obj.called_once)
@requests_mock.Mocker()
def test_mocker_delete(self, m):
mock_obj = m.delete(self.URL, text=self.TEXT)
self.assertResponse(requests.delete(self.URL))
self.assertTrue(mock_obj.called)
+ self.assertTrue(mock_obj.called_once)
+
+ @requests_mock.Mocker()
+ def test_mocker_real_http_and_responses(self, m):
+ self.assertRaises(RuntimeError,
+ m.get,
+ self.URL,
+ text='abcd',
+ real_http=True)
+
+ @requests_mock.Mocker()
+ def test_mocker_real_http(self, m):
+ data = 'testdata'
+
+ uri1 = 'fake://example.com/foo'
+ uri2 = 'fake://example.com/bar'
+ uri3 = 'fake://example.com/baz'
+
+ m.get(uri1, text=data)
+ m.get(uri2, real_http=True)
+
+ self.assertEqual(data, requests.get(uri1).text)
+
+ # This should fail because requests can't get an adapter for mock://
+ # but it shows that it has tried and would have made a request.
+ self.assertRaises(requests.exceptions.InvalidSchema,
+ requests.get,
+ uri2)
+
+ # This fails because real_http is not set on the mocker
+ self.assertRaises(exceptions.NoMockAddress,
+ requests.get,
+ uri3)
+
+ # do it again to make sure the mock is still in place
+ self.assertEqual(data, requests.get(uri1).text)
+
+ @requests_mock.Mocker(case_sensitive=True)
+ def test_case_sensitive_query(self, m):
+ data = 'testdata'
+ query = {'aBcDe': 'FgHiJ'}
+
+ m.get(self.URL, text=data)
+ resp = requests.get(self.URL, params=query)
+
+ self.assertEqual('GET', m.last_request.method)
+ self.assertEqual(200, resp.status_code)
+ self.assertEqual(data, resp.text)
+
+ for k, v in query.items():
+ self.assertEqual([v], m.last_request.qs[k])
+
+ @mock.patch.object(requests_mock.Mocker, 'case_sensitive', True)
+ def test_global_case_sensitive(self):
+ with requests_mock.mock() as m:
+ data = 'testdata'
+ query = {'aBcDe': 'FgHiJ'}
+
+ m.get(self.URL, text=data)
+ resp = requests.get(self.URL, params=query)
+
+ self.assertEqual('GET', m.last_request.method)
+ self.assertEqual(200, resp.status_code)
+ self.assertEqual(data, resp.text)
+
+ for k, v in query.items():
+ self.assertEqual([v], m.last_request.qs[k])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requests-mock-1.0.0/requests_mock.egg-info/PKG-INFO new/requests-mock-1.1.0/requests_mock.egg-info/PKG-INFO
--- old/requests-mock-1.0.0/requests_mock.egg-info/PKG-INFO 2016-05-09 07:14:35.000000000 +0200
+++ new/requests-mock-1.1.0/requests_mock.egg-info/PKG-INFO 2016-09-14 09:07:03.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: requests-mock
-Version: 1.0.0
+Version: 1.1.0
Summary: Mock out responses from the requests package
Home-page: https://requests-mock.readthedocs.org/
Author: Jamie Lennox
@@ -105,5 +105,5 @@
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
Classifier: Topic :: Software Development :: Testing
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requests-mock-1.0.0/requests_mock.egg-info/SOURCES.txt new/requests-mock-1.1.0/requests_mock.egg-info/SOURCES.txt
--- old/requests-mock-1.0.0/requests_mock.egg-info/SOURCES.txt 2016-05-09 07:14:35.000000000 +0200
+++ new/requests-mock-1.1.0/requests_mock.egg-info/SOURCES.txt 2016-09-14 09:07:03.000000000 +0200
@@ -19,6 +19,7 @@
docs/fixture.rst
docs/history.rst
docs/index.rst
+docs/knownissues.rst
docs/make.bat
docs/matching.rst
docs/mocker.rst
@@ -27,6 +28,9 @@
docs/response.rst
docs/api/modules.rst
docs/api/requests_mock.rst
+releasenotes/notes/Add-called_once-property-a69546448cbd5542.yaml
+releasenotes/notes/case-insensitive-matching-a3143221359bbf2d.yaml
+releasenotes/notes/fixture-extras-699a5b5fb5bd6aab.yaml
requests_mock/__init__.py
requests_mock/adapter.py
requests_mock/compat.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requests-mock-1.0.0/requests_mock.egg-info/pbr.json new/requests-mock-1.1.0/requests_mock.egg-info/pbr.json
--- old/requests-mock-1.0.0/requests_mock.egg-info/pbr.json 2016-05-09 07:14:35.000000000 +0200
+++ new/requests-mock-1.1.0/requests_mock.egg-info/pbr.json 2016-09-14 09:07:03.000000000 +0200
@@ -1 +1 @@
-{"is_release": true, "git_version": "a8b009c"}
\ No newline at end of file
+{"is_release": true, "git_version": "c105f1c"}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requests-mock-1.0.0/requests_mock.egg-info/requires.txt new/requests-mock-1.1.0/requests_mock.egg-info/requires.txt
--- old/requests-mock-1.0.0/requests_mock.egg-info/requires.txt 2016-05-09 07:14:35.000000000 +0200
+++ new/requests-mock-1.1.0/requests_mock.egg-info/requires.txt 2016-09-14 09:07:03.000000000 +0200
@@ -1,2 +1,5 @@
requests>=1.1
six
+
+[fixture]
+fixtures
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requests-mock-1.0.0/setup.cfg new/requests-mock-1.1.0/setup.cfg
--- old/requests-mock-1.0.0/setup.cfg 2016-05-09 07:14:35.000000000 +0200
+++ new/requests-mock-1.1.0/setup.cfg 2016-09-14 09:07:03.000000000 +0200
@@ -17,7 +17,7 @@
Programming Language :: Python :: 2.7
Programming Language :: Python :: 2.6
Programming Language :: Python :: 3
- Programming Language :: Python :: 3.3
+ Programming Language :: Python :: 3.4
Topic :: Software Development :: Testing
test_suite = requests_mock.tests
@@ -27,6 +27,10 @@
[wheel]
universal = 1
+[extras]
+fixture =
+ fixtures
+
[egg_info]
tag_build =
tag_date = 0