refactoring sendall
This commit is contained in:
@@ -332,7 +332,7 @@ class fakesock(object):
|
||||
self.fd.write(received)
|
||||
should_continue = len(received) > 0
|
||||
|
||||
except socket.error as e: #TODO: TEST THIS
|
||||
except socket.error as e:
|
||||
if e.errno == EAGAIN:
|
||||
continue
|
||||
break
|
||||
@@ -361,16 +361,13 @@ class fakesock(object):
|
||||
meta = dict(self._entry.request.headers)
|
||||
body = utf8(self._sent_data[-1])
|
||||
if meta.get('transfer-encoding', '') == 'chunked':
|
||||
if len(body) > 1 and body != '\r\n' and body != '0\r\n\r\n':
|
||||
if not body.isdigit() and body != '\r\n' and body != '0\r\n\r\n':
|
||||
self._entry.request.body += body
|
||||
else:
|
||||
self._entry.request.body += body
|
||||
|
||||
try:
|
||||
return httpretty.historify_request(headers, body, False)
|
||||
except Exception as e:
|
||||
logging.error(traceback.format_exc(e))
|
||||
return self.real_sendall(data, *args, **kw)
|
||||
httpretty.historify_request(headers, body, False)
|
||||
return
|
||||
|
||||
# path might come with
|
||||
s = urlsplit(path)
|
||||
@@ -391,14 +388,7 @@ class fakesock(object):
|
||||
self.real_sendall(data)
|
||||
return
|
||||
|
||||
self._entry = matcher.get_next_entry(method)
|
||||
# Attach more info to the entry
|
||||
# So the callback can be more clever about what to do
|
||||
# This does also fix the case where the callback
|
||||
# would be handed a compiled regex as uri instead of the
|
||||
# real uri
|
||||
self._entry.info = info
|
||||
self._entry.request = request
|
||||
self._entry = matcher.get_next_entry(method, info, request)
|
||||
|
||||
def debug(self, func, *a, **kw):
|
||||
if self.is_http:
|
||||
@@ -746,7 +736,7 @@ class URIMatcher(object):
|
||||
else:
|
||||
return wrap.format(self.regex.pattern)
|
||||
|
||||
def get_next_entry(self, method='GET'):
|
||||
def get_next_entry(self, method, info, request):
|
||||
"""Cycle through available responses, but only once.
|
||||
Any subsequent requests will receive the last response"""
|
||||
|
||||
@@ -766,6 +756,14 @@ class URIMatcher(object):
|
||||
entry = entries_for_method[self.current_entries[method]]
|
||||
if self.current_entries[method] != -1:
|
||||
self.current_entries[method] += 1
|
||||
|
||||
# Attach more info to the entry
|
||||
# So the callback can be more clever about what to do
|
||||
# This does also fix the case where the callback
|
||||
# would be handed a compiled regex as uri instead of the
|
||||
# real uri
|
||||
entry.info = info
|
||||
entry.request = request
|
||||
return entry
|
||||
|
||||
def __hash__(self):
|
||||
@@ -857,7 +855,7 @@ class httpretty(HttpBaseClass):
|
||||
def historify_request(cls, headers, body='', append=True):
|
||||
request = HTTPrettyRequest(headers, body)
|
||||
cls.last_request = request
|
||||
if append:
|
||||
if append or not cls.latest_requests:
|
||||
cls.latest_requests.append(request)
|
||||
else:
|
||||
cls.latest_requests[-1] = request
|
||||
|
||||
@@ -377,7 +377,6 @@ def test_fakesock_socket_real_sendall_socket_error(socket, old_socket):
|
||||
# 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')
|
||||
|
||||
@@ -458,3 +457,113 @@ def test_fakesock_socket_sendall_with_valid_requestline(POTENTIAL_HTTP_PORTS, ht
|
||||
|
||||
# When I try to send data
|
||||
socket.sendall("GET /foobar HTTP/1.1\r\nContent-Type: application/json\r\n\r\n")
|
||||
|
||||
|
||||
@patch('httpretty.core.old_socket')
|
||||
@patch('httpretty.core.httpretty')
|
||||
@patch('httpretty.core.POTENTIAL_HTTP_PORTS')
|
||||
def test_fakesock_socket_sendall_with_valid_requestline(POTENTIAL_HTTP_PORTS, httpretty, old_socket):
|
||||
("fakesock.socket#sendall should create an entry if it's given a valid request line")
|
||||
matcher = Mock()
|
||||
info = Mock()
|
||||
httpretty.match_uriinfo.return_value = (matcher, info)
|
||||
httpretty.register_uri(httpretty.GET, 'http://foo.com/foobar')
|
||||
|
||||
# Background:
|
||||
# using a subclass of socket that mocks out real_sendall
|
||||
class MySocket(fakesock.socket):
|
||||
def real_sendall(self, data, *args, **kw):
|
||||
raise AssertionError('should never call this...')
|
||||
|
||||
# Given an instance of that socket
|
||||
socket = MySocket()
|
||||
|
||||
# And that is is considered http
|
||||
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")
|
||||
|
||||
|
||||
@patch('httpretty.core.old_socket')
|
||||
@patch('httpretty.core.POTENTIAL_HTTP_PORTS')
|
||||
def test_fakesock_socket_sendall_with_body_data_no_entry(POTENTIAL_HTTP_PORTS, old_socket):
|
||||
("fakesock.socket#sendall should call real_sendall when not parsing headers and there is no entry")
|
||||
# Background:
|
||||
# Using a subclass of socket that mocks out real_sendall
|
||||
class MySocket(fakesock.socket):
|
||||
def real_sendall(self, data):
|
||||
data.should.equal('BLABLABLABLA')
|
||||
return 'cool'
|
||||
|
||||
# Given an instance of that socket
|
||||
socket = MySocket()
|
||||
socket._entry = None
|
||||
|
||||
# And that is is considered http
|
||||
socket.connect(('foo.com', 80))
|
||||
|
||||
# When I try to send data
|
||||
result = socket.sendall("BLABLABLABLA")
|
||||
|
||||
# Then the result should be the return value from real_sendall
|
||||
result.should.equal('cool')
|
||||
|
||||
|
||||
@patch('httpretty.core.old_socket')
|
||||
@patch('httpretty.core.POTENTIAL_HTTP_PORTS')
|
||||
def test_fakesock_socket_sendall_with_body_data_with_entry(POTENTIAL_HTTP_PORTS, old_socket):
|
||||
("fakesock.socket#sendall should call real_sendall when not ")
|
||||
# Background:
|
||||
# Using a subclass of socket that mocks out real_sendall
|
||||
class MySocket(fakesock.socket):
|
||||
def real_sendall(self, data):
|
||||
raise AssertionError('should have never been called')
|
||||
# Using a mocked entry
|
||||
entry = Mock()
|
||||
entry.request.headers = {}
|
||||
entry.request.body = ''
|
||||
|
||||
# Given an instance of that socket
|
||||
socket = MySocket()
|
||||
socket._entry = entry
|
||||
|
||||
|
||||
# And that is is considered http
|
||||
socket.connect(('foo.com', 80))
|
||||
|
||||
# When I try to send data
|
||||
socket.sendall("BLABLABLABLA")
|
||||
|
||||
# Then the entry should have that body
|
||||
entry.request.body.should.equal('BLABLABLABLA')
|
||||
|
||||
|
||||
@patch('httpretty.core.old_socket')
|
||||
@patch('httpretty.core.POTENTIAL_HTTP_PORTS')
|
||||
def test_fakesock_socket_sendall_with_body_data_with_chunked_entry(POTENTIAL_HTTP_PORTS, old_socket):
|
||||
("fakesock.socket#sendall should call real_sendall when not ")
|
||||
# Background:
|
||||
# Using a subclass of socket that mocks out real_sendall
|
||||
class MySocket(fakesock.socket):
|
||||
def real_sendall(self, data):
|
||||
raise AssertionError('should have never been called')
|
||||
# Using a mocked entry
|
||||
entry = Mock()
|
||||
entry.request.headers = {
|
||||
'transfer-encoding': 'chunked',
|
||||
}
|
||||
entry.request.body = ''
|
||||
|
||||
# Given an instance of that socket
|
||||
socket = MySocket()
|
||||
socket._entry = entry
|
||||
|
||||
# And that is is considered http
|
||||
socket.connect(('foo.com', 80))
|
||||
|
||||
# When I try to send data
|
||||
socket.sendall("BLABLABLABLA")
|
||||
|
||||
# Then the entry should have that body
|
||||
httpretty.last_request.body.should.equal('BLABLABLABLA')
|
||||
|
||||
Reference in New Issue
Block a user