From 472cc3bffea7dbff5d8879098185a2908de9aa42 Mon Sep 17 00:00:00 2001 From: Ivan Malison Date: Wed, 17 Sep 2014 23:22:43 -0700 Subject: [PATCH] use_cassette -> CassetteContextDecorator --- setup.py | 2 +- tests/unit/test_cassettes.py | 6 ++++-- tests/unit/test_vcr.py | 16 ++++++++++++++++ vcr/cassette.py | 16 +++++++++++++--- vcr/config.py | 2 +- 5 files changed, 35 insertions(+), 7 deletions(-) create mode 100644 tests/unit/test_vcr.py diff --git a/setup.py b/setup.py index 7d47d1f..0540e85 100644 --- a/setup.py +++ b/setup.py @@ -41,7 +41,7 @@ setup( 'vcr.compat': 'vcr/compat', 'vcr.persisters': 'vcr/persisters', }, - install_requires=['PyYAML', 'contextdecorator', 'six'], + install_requires=['PyYAML', 'six'], license='MIT', tests_require=['pytest', 'mock', 'pytest-localserver'], cmdclass={'test': PyTest}, diff --git a/tests/unit/test_cassettes.py b/tests/unit/test_cassettes.py index 1974e69..2589aa8 100644 --- a/tests/unit/test_cassettes.py +++ b/tests/unit/test_cassettes.py @@ -1,6 +1,9 @@ +from six.moves import http_client as httplib + import pytest import yaml import mock + from vcr.cassette import Cassette from vcr.errors import UnhandledHTTPRequestError @@ -73,8 +76,7 @@ def test_cassette_cant_read_same_request_twice(): @mock.patch('vcr.cassette.Cassette.can_play_response_for', return_value=True) @mock.patch('vcr.stubs.VCRHTTPResponse') def test_function_decorated_with_use_cassette_can_be_invoked_multiple_times(*args): - from six.moves import http_client as httplib - @Cassette.use_cassette('test') + @Cassette.use('test') def decorated_function(): conn = httplib.HTTPConnection("www.python.org") conn.request("GET", "/index.html") diff --git a/tests/unit/test_vcr.py b/tests/unit/test_vcr.py new file mode 100644 index 0000000..aaae969 --- /dev/null +++ b/tests/unit/test_vcr.py @@ -0,0 +1,16 @@ +import mock + +from vcr import VCR + + + +def test_vcr_use_cassette(): + filter_headers = mock.Mock() + test_vcr = VCR(filter_headers=filter_headers) + with mock.patch('vcr.config.Cassette') as mock_cassette_class: + @test_vcr.use_cassette('test') + def function(): + pass + mock_cassette_class.call_count == 0 + function() + assert mock_cassette_class.use.call_args[1]['filter_headers'] is filter_headers diff --git a/vcr/cassette.py b/vcr/cassette.py index b39ae9c..4b10f18 100644 --- a/vcr/cassette.py +++ b/vcr/cassette.py @@ -14,7 +14,15 @@ from .matchers import requests_match, uri, method from .errors import UnhandledHTTPRequestError -class use_cassette(object): +class CassetteContextDecorator(object): + """Context manager/decorator that handles installing the cassette and + removing cassettes. + + This class defers the creation of a new cassette instance until the point at + which it is installed by context manager or decorator. The fact that a new + cassette is used with each application prevents the state of any cassette + from interfering with another. + """ def __init__(self, cls, *args, **kwargs): self.args = args @@ -47,8 +55,10 @@ class Cassette(object): return new_cassette @classmethod - def use_cassette(cls, *args, **kwargs): - return use_cassette(cls, *args, **kwargs) + def use(cls, *args, **kwargs): + return CassetteContextDecorator(cls, *args, **kwargs) + + use_cassette = use def __init__(self, path, diff --git a/vcr/config.py b/vcr/config.py index 9f7a318..0727372 100644 --- a/vcr/config.py +++ b/vcr/config.py @@ -108,7 +108,7 @@ class VCR(object): ), } - return Cassette.use_cassette(path, **merged_config) + return Cassette.use(path, **merged_config) def register_serializer(self, name, serializer): self.serializers[name] = serializer