1
0
mirror of https://github.com/kevin1024/vcrpy.git synced 2025-12-09 01:03:24 +00:00

add allow_playback_repeats option to Cassette

This commit is contained in:
Tyson Holub
2020-07-02 10:10:49 -04:00
committed by Kevin McCarthy
parent a249781b97
commit 042ee790e2
4 changed files with 49 additions and 3 deletions

View File

@@ -33,6 +33,8 @@ consider part of the API. The fields are as follows:
been played back.
- ``responses_of(request)``: Access the responses that match a given
request
- ``allow_playback_repeats``: A boolean indicating whether responses
can be played back more than once.
The ``Request`` object has the following properties:
@@ -386,3 +388,19 @@ VCR.py allows to rewind a cassette in order to replay it inside the same functio
assert cass.all_played
cass.rewind()
assert not cass.all_played
Playback Repeats
----------------
By default, each response in a cassette can only be matched and played back
once while the cassette is in use, unless the cassette is rewound.
If you want to allow playback repeats without rewinding the cassette, use
the Cassette ``allow_playback_repeats`` option.
.. code:: python
with vcr.use_cassette('fixtures/vcr_cassettes/synopsis.yaml', allow_playback_repeats=True) as cass:
for x in range(10):
response = urllib2.urlopen('http://www.zombo.com/').read()
assert cass.all_played

View File

@@ -137,6 +137,31 @@ def test_cassette_all_played():
assert a.all_played
@mock.patch("vcr.cassette.requests_match", _mock_requests_match)
def test_cassette_allow_playback_repeats():
a = Cassette("test", allow_playback_repeats=True)
a.append("foo", "bar")
a.append("other", "resp")
for x in range(10):
assert a.play_response("foo") == "bar"
assert a.play_count == 10
assert a.all_played is False
assert a.play_response("other") == "resp"
assert a.play_count == 11
assert a.all_played
a.allow_playback_repeats = False
with pytest.raises(UnhandledHTTPRequestError) as e:
a.play_response("foo")
assert str(e.value) == "\"The cassette ('test') doesn't contain the request ('foo') asked for\""
a.rewind()
assert a.all_played is False
assert a.play_response("foo") == "bar"
assert a.all_played is False
assert a.play_response("other") == "resp"
assert a.all_played
@mock.patch("vcr.cassette.requests_match", _mock_requests_match)
def test_cassette_rewound():
a = Cassette("test")

View File

@@ -182,6 +182,7 @@ class Cassette:
before_record_response=None,
custom_patches=(),
inject=False,
allow_playback_repeats=False,
):
self._persister = persister or FilesystemPersister
self._path = path
@@ -193,6 +194,7 @@ class Cassette:
self.inject = inject
self.record_mode = record_mode
self.custom_patches = custom_patches
self.allow_playback_repeats = allow_playback_repeats
# self.data is the list of (req, resp) tuples
self.data = []
@@ -207,7 +209,7 @@ class Cassette:
@property
def all_played(self):
"""Returns True if all responses have been played, False otherwise."""
return self.play_count == len(self)
return len(self.play_counts.values()) == len(self)
@property
def requests(self):
@@ -259,7 +261,7 @@ class Cassette:
hasn't been played back before, and mark it as played
"""
for index, response in self._responses(request):
if self.play_counts[index] == 0:
if self.play_counts[index] == 0 or self.allow_playback_repeats:
self.play_counts[index] += 1
return response
# The cassette doesn't contain the request asked for.
@@ -349,6 +351,6 @@ class Cassette:
def __contains__(self, request):
"""Return whether or not a request has been stored"""
for index, response in self._responses(request):
if self.play_counts[index] == 0:
if self.play_counts[index] == 0 or self.allow_playback_repeats:
return True
return False

View File

@@ -149,6 +149,7 @@ class VCR:
"inject": kwargs.get("inject_cassette", self.inject_cassette),
"path_transformer": path_transformer,
"func_path_generator": func_path_generator,
"allow_playback_repeats": kwargs.get("allow_playback_repeats", False),
}
path = kwargs.get("path")
if path: