refactoring sendall

This commit is contained in:
Gabriel Falcao
2013-10-07 17:14:16 -04:00
parent ae5294f3f9
commit 217ce91b11
2 changed files with 125 additions and 18 deletions

View File

@@ -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

View File

@@ -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')