diff options
| author | Gabriel Falcao <gabriel@nacaolivre.org> | 2013-10-04 19:26:44 -0400 |
|---|---|---|
| committer | Gabriel Falcao <gabriel@nacaolivre.org> | 2013-10-04 19:26:44 -0400 |
| commit | 261b275ad7cad770adebcc6a44fdc17cc2f5c63c (patch) | |
| tree | b9907b32b630adead22fd8d92c90d3d8c6a8bed2 | |
| parent | 0443e321c205638825825442aadfee32644284fa (diff) | |
| download | httpretty-261b275ad7cad770adebcc6a44fdc17cc2f5c63c.tar.gz | |
more refactoring
| -rw-r--r-- | httpretty/core.py | 40 | ||||
| -rw-r--r-- | tests/unit/test_core.py | 34 |
2 files changed, 63 insertions, 11 deletions
diff --git a/httpretty/core.py b/httpretty/core.py index dd1610c..cf876a6 100644 --- a/httpretty/core.py +++ b/httpretty/core.py @@ -246,6 +246,7 @@ class fakesock(object): self.timeout = socket._GLOBAL_DEFAULT_TIMEOUT self._sock = self self.is_http = False + self._bufsize = 16 def getpeercert(self, *a, **kw): now = datetime.now() @@ -293,6 +294,12 @@ class fakesock(object): self._closed = True def makefile(self, mode='r', bufsize=-1): + """Returns this fake socket's own StringIO buffer. + + If there is an entry associated with the socket, the file + descriptor gets filled in with the entry data before being + returned. + """ self._mode = mode self._bufsize = bufsize @@ -301,18 +308,30 @@ class fakesock(object): return self.fd - def _true_sendall(self, data, *args, **kw): - if self.is_http: + def real_sendall(self, data, *args, **kw): + """Sends data to the remote server. This method is called + when HTTPretty identifies that someone is trying to send + non-http data. + + The received bytes are written in this socket's StringIO + buffer so that HTTPretty can return it accordingly when + necessary. + """ + if self.is_http: # no need to connect if `self.is_http` is + # False because self.connect already did + # that self.truesock.connect(self._address) + self.truesock.settimeout(0) self.truesock.sendall(data, *args, **kw) - _d = True - while _d: + should_continue = True + while should_continue: try: - _d = self.truesock.recv(16) - self.truesock.settimeout(0.0) - self.fd.write(_d) + received = self.truesock.recv(self._bufsize) + self.fd.write(received) + should_continue = len(received) > 0 + except socket.error as e: if e.errno == EAGAIN: continue @@ -321,7 +340,6 @@ class fakesock(object): self.fd.seek(0) def sendall(self, data, *args, **kw): - self._sent_data.append(data) self.fd.seek(0) try: @@ -333,7 +351,7 @@ class fakesock(object): if not self._entry: # If the previous request wasn't mocked, don't mock the subsequent sending of data - return self._true_sendall(data) + return self.real_sendall(data) if not is_parsing_headers: if len(self._sent_data) > 1: @@ -350,7 +368,7 @@ class fakesock(object): return httpretty.historify_request(headers, body, False) except Exception as e: logging.error(traceback.format_exc(e)) - return self._true_sendall(data, *args, **kw) + return self.real_sendall(data, *args, **kw) # path might come with s = urlsplit(path) @@ -373,7 +391,7 @@ class fakesock(object): if not entries: self._entry = None - self._true_sendall(data) + self.real_sendall(data) return self._entry = matcher.get_next_entry(method) diff --git a/tests/unit/test_core.py b/tests/unit/test_core.py index b165fb6..0c7985d 100644 --- a/tests/unit/test_core.py +++ b/tests/unit/test_core.py @@ -283,3 +283,37 @@ def test_fakesock_socket_makefile(old_socket): socket._mode.should.equal('rw') # And the bufsize should have been set in the socket instance socket._bufsize.should.equal(512) + + # And the entry should have been filled with that filedescriptor + socket._entry.fill_filekind.assert_called_once_with(fd) + + +@patch('httpretty.core.old_socket') +def test_fakesock_socket_real_sendall(old_socket): + ("fakesock.socket#real_sendall sends data and buffers " + "the response in the file descriptor") + # Background: the real socket will stop returning bytes after the + # first call + real_socket = old_socket.return_value + real_socket.recv.side_effect = ['response from server', ""] + + # 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') + + # Then it should have called sendall in the real socket + real_socket.sendall.assert_called_once_with("SOMEDATA", 'some extra args...', foo='bar') + + # And the timeout was set to 0 + real_socket.settimeout.assert_called_once_with(0) + + # And recv was called with the bufsize + real_socket.recv.assert_has_calls([ + call(16), + call(16), + ]) + + # And the buffer should contain the data from the server + socket.fd.getvalue().should.equal("response from server") |
