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

refactored, 1 failing test

This commit is contained in:
Julien Funk
2017-01-13 16:09:42 -05:00
parent 6f8486e0a2
commit a033bc729c
8 changed files with 41 additions and 69 deletions

View File

@@ -10,41 +10,31 @@ import vcr
from vcr.persisters.filesystem import FilesystemPersister from vcr.persisters.filesystem import FilesystemPersister
def test_overriding_save_cassette_with_callback(tmpdir, httpbin): def test_save_cassette_with_custom_persister(tmpdir, httpbin):
'''Ensure you can save a cassette using save_callback''' '''Ensure you can save a cassette using save_callback'''
my_vcr = vcr.VCR()
def save_callback(cassette_path, data): my_vcr.register_persister(FilesystemPersister)
FilesystemPersister.write(cassette_path, data)
# Check to make sure directory doesnt exist # Check to make sure directory doesnt exist
assert not os.path.exists(str(tmpdir.join('nonexistent'))) assert not os.path.exists(str(tmpdir.join('nonexistent')))
# Run VCR to create dir and cassette file using new save_cassette callback # Run VCR to create dir and cassette file using new save_cassette callback
with vcr.use_cassette( with my_vcr.use_cassette(str(tmpdir.join('nonexistent', 'cassette.yml'))):
str(tmpdir.join('nonexistent', 'cassette.yml')),
save_callback=save_callback
):
urlopen(httpbin.url).read() urlopen(httpbin.url).read()
# Callback should have made the file and the directory # Callback should have made the file and the directory
assert os.path.exists(str(tmpdir.join('nonexistent', 'cassette.yml'))) assert os.path.exists(str(tmpdir.join('nonexistent', 'cassette.yml')))
def test_overriding_load_cassette_with_callback(tmpdir, httpbin): def test_load_cassette_with_custom_persister(tmpdir, httpbin):
''' '''
Ensure you can load a cassette using load_callback Ensure you can load a cassette using load_callback
''' '''
my_vcr = vcr.VCR()
my_vcr.register_persister(FilesystemPersister)
test_fixture = str(tmpdir.join('synopsis.json')) test_fixture = str(tmpdir.join('synopsis.json'))
def load_callback(cassette_path): with my_vcr.use_cassette(test_fixture, serializer='json'):
with open(cassette_path) as f:
cassette_content = f.read()
return cassette_content
with vcr.use_cassette(
test_fixture,
serializer='json',
load_callback=load_callback
):
response = urlopen(httpbin.url).read() response = urlopen(httpbin.url).read()
assert b'difficult sometimes' in response assert b'difficult sometimes' in response

View File

@@ -1,6 +1,7 @@
import copy import copy
import inspect import inspect
import os import os
import sys
from six.moves import http_client as httplib from six.moves import http_client as httplib
import pytest import pytest
@@ -8,6 +9,7 @@ import yaml
from vcr.compat import mock, contextlib from vcr.compat import mock, contextlib
from vcr.cassette import Cassette from vcr.cassette import Cassette
from vcr.persisters.filesystem import FilesystemPersister
from vcr.errors import UnhandledHTTPRequestError from vcr.errors import UnhandledHTTPRequestError
from vcr.patch import force_reset from vcr.patch import force_reset
from vcr.stubs import VCRHTTPSConnection from vcr.stubs import VCRHTTPSConnection
@@ -83,7 +85,8 @@ def make_get_request():
@mock.patch('vcr.cassette.requests_match', return_value=True) @mock.patch('vcr.cassette.requests_match', return_value=True)
@mock.patch('vcr.cassette.load_cassette', lambda *args, **kwargs: (('foo',), (mock.MagicMock(),))) @mock.patch('vcr.cassette.FilesystemPersister.load_cassette',
lambda *args, **kwargs: (('foo',), (mock.MagicMock(),)))
@mock.patch('vcr.cassette.Cassette.can_play_response_for', return_value=True) @mock.patch('vcr.cassette.Cassette.can_play_response_for', return_value=True)
@mock.patch('vcr.stubs.VCRHTTPResponse') @mock.patch('vcr.stubs.VCRHTTPResponse')
def test_function_decorated_with_use_cassette_can_be_invoked_multiple_times(*args): def test_function_decorated_with_use_cassette_can_be_invoked_multiple_times(*args):

View File

@@ -1,6 +1,6 @@
import pytest import pytest
import vcr.persist from vcr.persisters.filesystem import FilesystemPersister
from vcr.serializers import jsonserializer, yamlserializer from vcr.serializers import jsonserializer, yamlserializer
@@ -10,7 +10,7 @@ from vcr.serializers import jsonserializer, yamlserializer
]) ])
def test_load_cassette_with_old_cassettes(cassette_path, serializer): def test_load_cassette_with_old_cassettes(cassette_path, serializer):
with pytest.raises(ValueError) as excinfo: with pytest.raises(ValueError) as excinfo:
vcr.persist.load_cassette(cassette_path, serializer) FilesystemPersister.load_cassette(cassette_path, serializer)
assert "run the migration script" in excinfo.exconly() assert "run the migration script" in excinfo.exconly()
@@ -20,5 +20,5 @@ def test_load_cassette_with_old_cassettes(cassette_path, serializer):
]) ])
def test_load_cassette_with_invalid_cassettes(cassette_path, serializer): def test_load_cassette_with_invalid_cassettes(cassette_path, serializer):
with pytest.raises(Exception) as excinfo: with pytest.raises(Exception) as excinfo:
vcr.persist.load_cassette(cassette_path, serializer) FilesystemPersister.load_cassette(cassette_path, serializer)
assert "run the migration script" not in excinfo.exconly() assert "run the migration script" not in excinfo.exconly()

View File

@@ -94,7 +94,7 @@ def test_vcr_before_record_response_iterable():
response = object() # just can't be None response = object() # just can't be None
# Prevent actually saving the cassette # Prevent actually saving the cassette
with mock.patch('vcr.cassette.save_cassette'): with mock.patch('vcr.cassette.FilesystemPersister.save_cassette'):
# Baseline: non-iterable before_record_response should work # Baseline: non-iterable before_record_response should work
mock_filter = mock.Mock() mock_filter = mock.Mock()
@@ -118,7 +118,7 @@ def test_before_record_response_as_filter():
response = object() # just can't be None response = object() # just can't be None
# Prevent actually saving the cassette # Prevent actually saving the cassette
with mock.patch('vcr.cassette.save_cassette'): with mock.patch('vcr.cassette.FilesystemPersister.save_cassette'):
filter_all = mock.Mock(return_value=None) filter_all = mock.Mock(return_value=None)
vcr = VCR(before_record_response=filter_all) vcr = VCR(before_record_response=filter_all)
@@ -132,7 +132,7 @@ def test_vcr_path_transformer():
# Regression test for #199 # Regression test for #199
# Prevent actually saving the cassette # Prevent actually saving the cassette
with mock.patch('vcr.cassette.save_cassette'): with mock.patch('vcr.cassette.FilesystemPersister.save_cassette'):
# Baseline: path should be unchanged # Baseline: path should be unchanged
vcr = VCR() vcr = VCR()

View File

@@ -8,8 +8,8 @@ from .compat import contextlib, collections
from .errors import UnhandledHTTPRequestError from .errors import UnhandledHTTPRequestError
from .matchers import requests_match, uri, method from .matchers import requests_match, uri, method
from .patch import CassettePatcherBuilder from .patch import CassettePatcherBuilder
from .persist import load_cassette, save_cassette
from .serializers import yamlserializer from .serializers import yamlserializer
from .persisters.filesystem import FilesystemPersister
from .util import partition_dict from .util import partition_dict
@@ -163,16 +163,13 @@ class Cassette(object):
def use(cls, **kwargs): def use(cls, **kwargs):
return CassetteContextDecorator.from_args(cls, **kwargs) return CassetteContextDecorator.from_args(cls, **kwargs)
def __init__(self, path, serializer=yamlserializer, save_callback=None, def __init__(self, path, serializer=yamlserializer, persister=FilesystemPersister, record_mode='once',
load_callback=None, record_mode='once',
match_on=(uri, method), before_record_request=None, match_on=(uri, method), before_record_request=None,
before_record_response=None, custom_patches=(), before_record_response=None, custom_patches=(),
inject=False): inject=False):
self._persister = persister
self._path = path self._path = path
self._serializer = serializer self._serializer = serializer
self._save_callback = save_callback
self._load_callback = load_callback
self._match_on = match_on self._match_on = match_on
self._before_record_request = before_record_request or (lambda x: x) self._before_record_request = before_record_request or (lambda x: x)
self._before_record_response = before_record_response or (lambda x: x) self._before_record_response = before_record_response or (lambda x: x)
@@ -274,20 +271,18 @@ class Cassette(object):
def _save(self, force=False): def _save(self, force=False):
if force or self.dirty: if force or self.dirty:
save_cassette( self._persister.save_cassette(
self._path, self._path,
self._as_dict(), self._as_dict(),
serializer=self._serializer, serializer=self._serializer,
save_callback=self._save_callback
) )
self.dirty = False self.dirty = False
def _load(self): def _load(self):
try: try:
requests, responses = load_cassette( requests, responses = self._persister.load_cassette(
self._path, self._path,
serializer=self._serializer, serializer=self._serializer,
load_callback=self._load_callback
) )
for request, response in zip(requests, responses): for request, response in zip(requests, responses):
self.append(request, response) self.append(request, response)

View File

@@ -9,6 +9,7 @@ import six
from .compat import collections from .compat import collections
from .cassette import Cassette from .cassette import Cassette
from .serializers import yamlserializer, jsonserializer from .serializers import yamlserializer, jsonserializer
from .persisters.filesystem import FilesystemPersister
from .util import compose, auto_decorate from .util import compose, auto_decorate
from . import matchers from . import matchers
from . import filters from . import filters
@@ -36,8 +37,7 @@ class VCR(object):
match_on=('method', 'scheme', 'host', 'port', 'path', 'query'), match_on=('method', 'scheme', 'host', 'port', 'path', 'query'),
before_record=None, inject_cassette=False, serializer='yaml', before_record=None, inject_cassette=False, serializer='yaml',
cassette_library_dir=None, func_path_generator=None, cassette_library_dir=None, func_path_generator=None,
decode_compressed_response=False, save_callback=None, decode_compressed_response=False):
load_callback=None):
self.serializer = serializer self.serializer = serializer
self.match_on = match_on self.match_on = match_on
self.cassette_library_dir = cassette_library_dir self.cassette_library_dir = cassette_library_dir
@@ -58,6 +58,7 @@ class VCR(object):
'raw_body': matchers.raw_body, 'raw_body': matchers.raw_body,
'body': matchers.body, 'body': matchers.body,
} }
self.persister = FilesystemPersister
self.record_mode = record_mode self.record_mode = record_mode
self.filter_headers = filter_headers self.filter_headers = filter_headers
self.filter_query_parameters = filter_query_parameters self.filter_query_parameters = filter_query_parameters
@@ -70,8 +71,6 @@ class VCR(object):
self.path_transformer = path_transformer self.path_transformer = path_transformer
self.func_path_generator = func_path_generator self.func_path_generator = func_path_generator
self.decode_compressed_response = decode_compressed_response self.decode_compressed_response = decode_compressed_response
self.save_callback = save_callback
self.load_callback = load_callback
self._custom_patches = tuple(custom_patches) self._custom_patches = tuple(custom_patches)
def _get_serializer(self, serializer_name): def _get_serializer(self, serializer_name):
@@ -150,8 +149,6 @@ class VCR(object):
tuple(matcher_names) + tuple(additional_matchers) tuple(matcher_names) + tuple(additional_matchers)
), ),
'record_mode': kwargs.get('record_mode', self.record_mode), 'record_mode': kwargs.get('record_mode', self.record_mode),
'save_callback': kwargs.get('save_callback', self.save_callback),
'load_callback': kwargs.get('load_callback', self.load_callback),
'before_record_request': self._build_before_record_request(kwargs), 'before_record_request': self._build_before_record_request(kwargs),
'before_record_response': self._build_before_record_response(kwargs), 'before_record_response': self._build_before_record_response(kwargs),
'custom_patches': self._custom_patches + kwargs.get( 'custom_patches': self._custom_patches + kwargs.get(
@@ -275,6 +272,10 @@ class VCR(object):
def register_matcher(self, name, matcher): def register_matcher(self, name, matcher):
self.matchers[name] = matcher self.matchers[name] = matcher
def register_persister(self, persister):
# Singleton, no name required
self.persister = persister
def test_case(self, predicate=None): def test_case(self, predicate=None):
predicate = predicate or self.is_test_method predicate = predicate or self.is_test_method
return six.with_metaclass(auto_decorate(self.use_cassette, predicate)) return six.with_metaclass(auto_decorate(self.use_cassette, predicate))

View File

@@ -1,26 +0,0 @@
from .persisters.filesystem import FilesystemPersister
from .serialize import serialize, deserialize
def load_cassette(cassette_path, serializer, load_callback=None):
# Injected `load_callback` must return a cassette or raise IOError
if load_callback is None:
with open(cassette_path) as f:
cassette_content = f.read()
else:
cassette_content = load_callback(cassette_path)
cassette = deserialize(cassette_content, serializer)
return cassette
def save_cassette(
cassette_path,
cassette_dict,
serializer,
save_callback=None
):
data = serialize(cassette_dict, serializer)
if save_callback is None:
FilesystemPersister.write(cassette_path, data)
else:
save_callback(cassette_path, data)

View File

@@ -1,9 +1,18 @@
import os import os
from ..serialize import serialize, deserialize
class FilesystemPersister(object): class FilesystemPersister(object):
@classmethod @classmethod
def write(cls, cassette_path, data): def load_cassette(cls, cassette_path, serializer):
with open(cassette_path) as f:
cassette_content = f.read()
cassette = deserialize(cassette_content, serializer)
return cassette
@staticmethod
def save_cassette(cassette_path, cassette_dict, serializer):
data = serialize(cassette_dict, serializer)
dirname, filename = os.path.split(cassette_path) dirname, filename = os.path.split(cassette_path)
if dirname and not os.path.exists(dirname): if dirname and not os.path.exists(dirname):
os.makedirs(dirname) os.makedirs(dirname)