vcr 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.gitignore +27 -0
- data/CHANGELOG.md +13 -0
- data/Gemfile +24 -0
- data/Gemfile.lock +119 -0
- data/README.md +3 -6
- data/Rakefile +70 -0
- data/benchmarks/http_stubbing_libraries.rb +59 -0
- data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/regex_cassette.yml +43 -0
- data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette1.yml +43 -0
- data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette2.yml +63 -0
- data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette3.yml +85 -0
- data/features/fixtures/vcr_cassettes/1.9.1/erb_cassette.yml +36 -0
- data/features/fixtures/vcr_cassettes/1.9.1/match_requests_on.yml +35 -0
- data/features/fixtures/vcr_cassettes/1.9.1/nested_replay_cassette.yml +32 -0
- data/features/fixtures/vcr_cassettes/1.9.1/not_the_real_response.yml +43 -0
- data/features/fixtures/vcr_cassettes/1.9.1/replay_localhost_cassette.yml +32 -0
- data/features/fixtures/vcr_cassettes/not_1.9.1/cucumber_tags/regex_cassette.yml +43 -0
- data/features/fixtures/vcr_cassettes/not_1.9.1/cucumber_tags/replay_cassette1.yml +43 -0
- data/features/fixtures/vcr_cassettes/not_1.9.1/cucumber_tags/replay_cassette2.yml +47 -0
- data/features/fixtures/vcr_cassettes/not_1.9.1/cucumber_tags/replay_cassette3.yml +85 -0
- data/features/fixtures/vcr_cassettes/not_1.9.1/erb_cassette.yml +36 -0
- data/features/fixtures/vcr_cassettes/not_1.9.1/match_requests_on.yml +35 -0
- data/features/fixtures/vcr_cassettes/not_1.9.1/nested_replay_cassette.yml +24 -0
- data/features/fixtures/vcr_cassettes/not_1.9.1/not_the_real_response.yml +43 -0
- data/features/fixtures/vcr_cassettes/not_1.9.1/replay_localhost_cassette.yml +32 -0
- data/features/http_client.feature +16 -0
- data/features/net_http.feature +27 -0
- data/features/record_response.feature +66 -0
- data/features/replay_recorded_response.feature +96 -0
- data/features/step_definitions/http_client_steps.rb +7 -0
- data/features/step_definitions/net_http_steps.rb +37 -0
- data/features/step_definitions/vcr_steps.rb +240 -0
- data/features/support/env.rb +104 -0
- data/features/webmock.feature +26 -0
- data/lib/vcr.rb +2 -2
- data/lib/vcr/extensions/net_http.rb +0 -8
- data/lib/vcr/http_stubbing_adapters/common.rb +39 -0
- data/lib/vcr/http_stubbing_adapters/fakeweb.rb +74 -70
- data/lib/vcr/http_stubbing_adapters/webmock.rb +61 -62
- data/lib/vcr/version.rb +1 -1
- data/spec/cassette_spec.rb +280 -0
- data/spec/config_spec.rb +76 -0
- data/spec/cucumber_tags_spec.rb +55 -0
- data/spec/deprecations_spec.rb +52 -0
- data/spec/extensions/net_http_response_spec.rb +85 -0
- data/spec/extensions/net_http_spec.rb +77 -0
- data/spec/fixtures/1.9.1/0_3_1_cassette.yml +29 -0
- data/spec/fixtures/1.9.1/cassette_spec/erb_with_no_vars.yml +32 -0
- data/spec/fixtures/1.9.1/cassette_spec/erb_with_vars.yml +32 -0
- data/spec/fixtures/1.9.1/cassette_spec/example.yml +110 -0
- data/spec/fixtures/1.9.1/cassette_spec/with_localhost_requests.yml +86 -0
- data/spec/fixtures/1.9.1/example_net_http.yml +14 -0
- data/spec/fixtures/1.9.1/example_net_http_request.yml +12 -0
- data/spec/fixtures/1.9.1/example_net_http_response.yml +25 -0
- data/spec/fixtures/1.9.1/fake_example.com_responses.yml +106 -0
- data/spec/fixtures/1.9.1/match_requests_on.yml +185 -0
- data/spec/fixtures/not_1.9.1/0_3_1_cassette.yml +29 -0
- data/spec/fixtures/not_1.9.1/cassette_spec/erb_with_no_vars.yml +32 -0
- data/spec/fixtures/not_1.9.1/cassette_spec/erb_with_vars.yml +32 -0
- data/spec/fixtures/not_1.9.1/cassette_spec/example.yml +110 -0
- data/spec/fixtures/not_1.9.1/cassette_spec/with_localhost_requests.yml +86 -0
- data/spec/fixtures/not_1.9.1/example_net_http.yml +14 -0
- data/spec/fixtures/not_1.9.1/example_net_http_request.yml +12 -0
- data/spec/fixtures/not_1.9.1/example_net_http_response.yml +25 -0
- data/spec/fixtures/not_1.9.1/fake_example.com_responses.yml +106 -0
- data/spec/fixtures/not_1.9.1/match_requests_on.yml +185 -0
- data/spec/http_stubbing_adapters/fakeweb_spec.rb +35 -0
- data/spec/http_stubbing_adapters/webmock_spec.rb +35 -0
- data/spec/request_matcher_spec.rb +194 -0
- data/spec/spec_helper.rb +40 -0
- data/spec/structs_spec.rb +121 -0
- data/spec/support/disable_warnings.rb +12 -0
- data/spec/support/http_library_adapters.rb +272 -0
- data/spec/support/http_stubbing_adapter.rb +100 -0
- data/spec/support/pending_on_heroku.rb +14 -0
- data/spec/support/temp_cassette_library_dir.rb +16 -0
- data/spec/support/vcr_localhost_server.rb +53 -0
- data/spec/vcr_spec.rb +198 -0
- data/spec/version_spec.rb +11 -0
- data/vcr.gemspec +43 -0
- metadata +134 -73
- data/lib/vcr/http_stubbing_adapters/base.rb +0 -36
- data/lib/vcr/version.rbc +0 -572
@@ -0,0 +1,39 @@
|
|
1
|
+
module VCR
|
2
|
+
module HttpStubbingAdapters
|
3
|
+
autoload :FakeWeb, 'vcr/http_stubbing_adapters/fakeweb'
|
4
|
+
autoload :WebMock, 'vcr/http_stubbing_adapters/webmock'
|
5
|
+
|
6
|
+
class UnsupportedRequestMatchAttributeError < ArgumentError; end
|
7
|
+
|
8
|
+
module Common
|
9
|
+
def check_version!
|
10
|
+
version_too_low, version_too_high = compare_version
|
11
|
+
|
12
|
+
if version_too_low
|
13
|
+
raise "You are using #{library_name} #{version}. VCR requires version #{self::VERSION_REQUIREMENT} or greater."
|
14
|
+
elsif version_too_high
|
15
|
+
warn "You are using #{library_name} #{version}. VCR is known to work with #{library_name} ~> #{self::VERSION_REQUIREMENT}. It may not work with this version."
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def compare_version
|
22
|
+
major, minor, patch = *version.split('.').map { |v| v.to_i }
|
23
|
+
req_major, req_minor, req_patch = *self::VERSION_REQUIREMENT.split('.').map { |v| v.to_i }
|
24
|
+
|
25
|
+
return true, false if major < req_major
|
26
|
+
return false, true if major > req_major
|
27
|
+
|
28
|
+
return true, false if minor < req_minor
|
29
|
+
return false, true if minor > req_minor
|
30
|
+
|
31
|
+
return patch < req_patch, false
|
32
|
+
end
|
33
|
+
|
34
|
+
def library_name
|
35
|
+
@library_name ||= self.to_s.split('::').last
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -3,94 +3,98 @@ require 'vcr/extensions/net_http'
|
|
3
3
|
|
4
4
|
module VCR
|
5
5
|
module HttpStubbingAdapters
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
def check_version!
|
11
|
-
unless meets_version_requirement?(::FakeWeb::VERSION, '1.2.8')
|
12
|
-
raise "You are using FakeWeb #{::FakeWeb::VERSION}. VCR requires version 1.2.8 or greater."
|
13
|
-
end
|
14
|
-
end
|
6
|
+
module FakeWeb
|
7
|
+
include VCR::HttpStubbingAdapters::Common
|
8
|
+
extend self
|
15
9
|
|
16
|
-
|
17
|
-
|
18
|
-
end
|
10
|
+
UNSUPPORTED_REQUEST_MATCH_ATTRIBUTES = [:body, :headers].freeze
|
11
|
+
LOCALHOST_REGEX = %r|\Ahttps?://((\w+:)?\w+@)?(#{VCR::LOCALHOST_ALIASES.map { |a| Regexp.escape(a) }.join('|')})(:\d+)?/|i
|
19
12
|
|
20
|
-
|
21
|
-
::FakeWeb.allow_net_connect = value
|
22
|
-
end
|
13
|
+
VERSION_REQUIREMENT = '1.3.0'
|
23
14
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
http_interactions.each do |i|
|
29
|
-
requests[i.request.matcher(match_attributes)] += [i.response]
|
30
|
-
end
|
31
|
-
|
32
|
-
requests.each do |request_matcher, responses|
|
33
|
-
::FakeWeb.register_uri(
|
34
|
-
request_matcher.method || :any,
|
35
|
-
request_matcher.uri,
|
36
|
-
responses.map{ |r| response_hash(r) }
|
37
|
-
)
|
38
|
-
end
|
39
|
-
end
|
15
|
+
def http_connections_allowed?
|
16
|
+
!!::FakeWeb.allow_net_connect?("http://some.url/besides/localhost")
|
17
|
+
end
|
40
18
|
|
41
|
-
|
42
|
-
|
43
|
-
|
19
|
+
def http_connections_allowed=(value)
|
20
|
+
@http_connections_allowed = value
|
21
|
+
update_fakeweb_allow_net_connect
|
22
|
+
end
|
44
23
|
|
45
|
-
|
46
|
-
|
24
|
+
def stub_requests(http_interactions, match_attributes)
|
25
|
+
validate_match_attributes(match_attributes)
|
26
|
+
requests = Hash.new { |h,k| h[k] = [] }
|
27
|
+
|
28
|
+
http_interactions.each do |i|
|
29
|
+
requests[i.request.matcher(match_attributes)] << i.response
|
47
30
|
end
|
48
31
|
|
49
|
-
|
50
|
-
|
51
|
-
|
32
|
+
requests.each do |request_matcher, responses|
|
33
|
+
::FakeWeb.register_uri(
|
34
|
+
request_matcher.method || :any,
|
35
|
+
request_matcher.uri,
|
36
|
+
responses.map{ |r| response_hash(r) }
|
37
|
+
)
|
52
38
|
end
|
39
|
+
end
|
53
40
|
|
54
|
-
|
55
|
-
|
56
|
-
|
41
|
+
def create_stubs_checkpoint(checkpoint_name)
|
42
|
+
checkpoints[checkpoint_name] = ::FakeWeb::Registry.instance.uri_map.dup
|
43
|
+
end
|
57
44
|
|
58
|
-
|
59
|
-
|
45
|
+
def restore_stubs_checkpoint(checkpoint_name)
|
46
|
+
::FakeWeb::Registry.instance.uri_map = checkpoints.delete(checkpoint_name)
|
47
|
+
end
|
60
48
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
userinfo = ""
|
66
|
-
end
|
49
|
+
def request_stubbed?(request, match_attributes)
|
50
|
+
validate_match_attributes(match_attributes)
|
51
|
+
::FakeWeb.registered_uri?(request.method, request.uri)
|
52
|
+
end
|
67
53
|
|
68
|
-
|
69
|
-
|
54
|
+
def request_uri(net_http, request)
|
55
|
+
::FakeWeb::Utility.request_uri_as_string(net_http, request)
|
56
|
+
end
|
70
57
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
58
|
+
def ignore_localhost=(value)
|
59
|
+
@ignore_localhost = value
|
60
|
+
update_fakeweb_allow_net_connect
|
61
|
+
end
|
75
62
|
|
76
|
-
|
63
|
+
def ignore_localhost?
|
64
|
+
@ignore_localhost
|
65
|
+
end
|
77
66
|
|
78
|
-
|
79
|
-
@checkpoints ||= {}
|
80
|
-
end
|
67
|
+
private
|
81
68
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
69
|
+
def version
|
70
|
+
::FakeWeb::VERSION
|
71
|
+
end
|
72
|
+
|
73
|
+
def update_fakeweb_allow_net_connect
|
74
|
+
::FakeWeb.allow_net_connect = if @http_connections_allowed
|
75
|
+
true
|
76
|
+
elsif @ignore_localhost
|
77
|
+
LOCALHOST_REGEX
|
78
|
+
else
|
79
|
+
false
|
87
80
|
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def checkpoints
|
84
|
+
@checkpoints ||= {}
|
85
|
+
end
|
86
|
+
|
87
|
+
def response_hash(response)
|
88
|
+
response.headers.merge(
|
89
|
+
:body => response.body,
|
90
|
+
:status => [response.status.code.to_s, response.status.message]
|
91
|
+
)
|
92
|
+
end
|
88
93
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
end
|
94
|
+
def validate_match_attributes(match_attributes)
|
95
|
+
invalid_attributes = match_attributes & UNSUPPORTED_REQUEST_MATCH_ATTRIBUTES
|
96
|
+
if invalid_attributes.size > 0
|
97
|
+
raise UnsupportedRequestMatchAttributeError.new("FakeWeb does not support matching requests on #{invalid_attributes.join(' or ')}")
|
94
98
|
end
|
95
99
|
end
|
96
100
|
end
|
@@ -3,86 +3,85 @@ require 'vcr/extensions/net_http'
|
|
3
3
|
|
4
4
|
module VCR
|
5
5
|
module HttpStubbingAdapters
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
def check_version!
|
11
|
-
unless meets_version_requirement?(::WebMock.version, VERSION_REQUIREMENT)
|
12
|
-
raise "You are using WebMock #{::WebMock.version}. VCR requires version #{VERSION_REQUIREMENT} or greater."
|
13
|
-
end
|
14
|
-
end
|
6
|
+
module WebMock
|
7
|
+
include VCR::HttpStubbingAdapters::Common
|
8
|
+
extend self
|
15
9
|
|
16
|
-
|
17
|
-
::WebMock::Config.instance.allow_net_connect
|
18
|
-
end
|
10
|
+
VERSION_REQUIREMENT = '1.3.3'
|
19
11
|
|
20
|
-
|
21
|
-
|
22
|
-
|
12
|
+
def http_connections_allowed?
|
13
|
+
::WebMock::Config.instance.allow_net_connect
|
14
|
+
end
|
23
15
|
|
24
|
-
|
25
|
-
|
16
|
+
def http_connections_allowed=(value)
|
17
|
+
::WebMock::Config.instance.allow_net_connect = value
|
18
|
+
end
|
26
19
|
|
27
|
-
|
28
|
-
|
29
|
-
end
|
20
|
+
def stub_requests(http_interactions, match_attributes)
|
21
|
+
requests = Hash.new { |h,k| h[k] = [] }
|
30
22
|
|
31
|
-
|
32
|
-
|
23
|
+
http_interactions.each do |i|
|
24
|
+
requests[i.request.matcher(match_attributes)] << i.response
|
25
|
+
end
|
33
26
|
|
34
|
-
|
35
|
-
|
27
|
+
requests.each do |request_matcher, responses|
|
28
|
+
stub = ::WebMock.stub_request(request_matcher.method || :any, request_matcher.uri)
|
36
29
|
|
37
|
-
|
38
|
-
|
39
|
-
end
|
30
|
+
with_hash = request_signature_hash(request_matcher)
|
31
|
+
stub = stub.with(with_hash) if with_hash.size > 0
|
40
32
|
|
41
|
-
|
42
|
-
checkpoints[checkpoint_name] = ::WebMock::RequestRegistry.instance.request_stubs.dup
|
33
|
+
stub.to_return(responses.map{ |r| response_hash(r) })
|
43
34
|
end
|
35
|
+
end
|
44
36
|
|
45
|
-
|
46
|
-
|
47
|
-
|
37
|
+
def create_stubs_checkpoint(checkpoint_name)
|
38
|
+
checkpoints[checkpoint_name] = ::WebMock::RequestRegistry.instance.request_stubs.dup
|
39
|
+
end
|
48
40
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
41
|
+
def restore_stubs_checkpoint(checkpoint_name)
|
42
|
+
::WebMock::RequestRegistry.instance.request_stubs = checkpoints.delete(checkpoint_name)
|
43
|
+
end
|
53
44
|
|
54
|
-
|
55
|
-
|
56
|
-
|
45
|
+
def request_stubbed?(request, match_attributes)
|
46
|
+
matcher = request.matcher(match_attributes)
|
47
|
+
!!::WebMock.registered_request?(::WebMock::RequestSignature.new(matcher.method || :any, request.uri, request_signature_hash(matcher)))
|
48
|
+
end
|
57
49
|
|
58
|
-
|
59
|
-
|
60
|
-
|
50
|
+
def request_uri(net_http, request)
|
51
|
+
::WebMock::NetHTTPUtility.request_signature_from_request(net_http, request).uri.to_s
|
52
|
+
end
|
61
53
|
|
62
|
-
|
63
|
-
|
64
|
-
|
54
|
+
def ignore_localhost=(value)
|
55
|
+
::WebMock::Config.instance.allow_localhost = value
|
56
|
+
end
|
65
57
|
|
66
|
-
|
58
|
+
def ignore_localhost?
|
59
|
+
::WebMock::Config.instance.allow_localhost
|
60
|
+
end
|
67
61
|
|
68
|
-
|
69
|
-
signature = {}
|
70
|
-
signature[:body] = request_matcher.body if request_matcher.match_requests_on?(:body)
|
71
|
-
signature[:headers] = request_matcher.headers if request_matcher.match_requests_on?(:headers)
|
72
|
-
signature
|
73
|
-
end
|
62
|
+
private
|
74
63
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
:status => [response.status.code.to_i, response.status.message],
|
79
|
-
:headers => response.headers
|
80
|
-
}
|
81
|
-
end
|
64
|
+
def version
|
65
|
+
::WebMock.version
|
66
|
+
end
|
82
67
|
|
83
|
-
|
84
|
-
|
85
|
-
|
68
|
+
def request_signature_hash(request_matcher)
|
69
|
+
signature = {}
|
70
|
+
signature[:body] = request_matcher.body if request_matcher.match_requests_on?(:body)
|
71
|
+
signature[:headers] = request_matcher.headers if request_matcher.match_requests_on?(:headers)
|
72
|
+
signature
|
73
|
+
end
|
74
|
+
|
75
|
+
def response_hash(response)
|
76
|
+
{
|
77
|
+
:body => response.body,
|
78
|
+
:status => [response.status.code.to_i, response.status.message],
|
79
|
+
:headers => response.headers
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
83
|
+
def checkpoints
|
84
|
+
@checkpoints ||= {}
|
86
85
|
end
|
87
86
|
end
|
88
87
|
end
|
data/lib/vcr/version.rb
CHANGED
@@ -0,0 +1,280 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe VCR::Cassette do
|
4
|
+
describe '#file' do
|
5
|
+
temp_dir File.expand_path(File.dirname(__FILE__) + '/fixtures/file'), :assign_to_cassette_library_dir => true
|
6
|
+
|
7
|
+
it 'combines the cassette_library_dir with the cassette name' do
|
8
|
+
cassette = VCR::Cassette.new('the_file')
|
9
|
+
cassette.file.should == File.join(VCR::Config.cassette_library_dir, 'the_file.yml')
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'strips out disallowed characters so that it is a valid file name with no spaces' do
|
13
|
+
cassette = VCR::Cassette.new("\nthis \t! is-the_13212_file name")
|
14
|
+
cassette.file.should =~ /#{Regexp.escape('_this_is-the_13212_file_name.yml')}$/
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'keeps any path separators' do
|
18
|
+
cassette = VCR::Cassette.new("dir/file_name")
|
19
|
+
cassette.file.should =~ /#{Regexp.escape('dir/file_name.yml')}$/
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'returns nil if the cassette_library_dir is not set' do
|
23
|
+
VCR::Config.cassette_library_dir = nil
|
24
|
+
cassette = VCR::Cassette.new('the_file')
|
25
|
+
cassette.file.should be_nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#record_http_interaction' do
|
30
|
+
it 'adds the interaction to #recorded_interactions' do
|
31
|
+
cassette = VCR::Cassette.new(:test_cassette)
|
32
|
+
cassette.recorded_interactions.should == []
|
33
|
+
cassette.record_http_interaction(:the_interaction)
|
34
|
+
cassette.recorded_interactions.should == [:the_interaction]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#match_requests_on' do
|
39
|
+
before(:each) { VCR::Config.default_cassette_options.merge!(:match_requests_on => [:uri, :method]) }
|
40
|
+
|
41
|
+
it "returns the provided options" do
|
42
|
+
c = VCR::Cassette.new('example', :match_requests_on => [:uri])
|
43
|
+
c.match_requests_on.should == [:uri]
|
44
|
+
end
|
45
|
+
|
46
|
+
it "returns a the default #match_requests_on when it has not been specified for the cassette" do
|
47
|
+
c = VCR::Cassette.new('example')
|
48
|
+
c.match_requests_on.should == [:uri, :method]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'on creation' do
|
53
|
+
it 'raises an error with a helpful message when loading an old unsupported cassette' do
|
54
|
+
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}")
|
55
|
+
lambda { VCR::Cassette.new('0_3_1_cassette') }.should raise_error(/The VCR cassette 0_3_1_cassette.yml uses an old format that is now deprecated/)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "raises an error if given an invalid record mode" do
|
59
|
+
lambda { VCR::Cassette.new(:test, :record => :not_a_record_mode) }.should raise_error(ArgumentError)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'raises an error if given invalid options' do
|
63
|
+
expect {
|
64
|
+
VCR::Cassette.new(:test, :invalid => :option)
|
65
|
+
}.to raise_error(ArgumentError)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'creates a stubs checkpoint on the http_stubbing_adapter' do
|
69
|
+
VCR.http_stubbing_adapter.should_receive(:create_stubs_checkpoint).with('example').once
|
70
|
+
VCR::Cassette.new('example')
|
71
|
+
end
|
72
|
+
|
73
|
+
describe 'ERB support' do
|
74
|
+
before(:each) do
|
75
|
+
@orig_default_options = VCR::Config.default_cassette_options
|
76
|
+
end
|
77
|
+
|
78
|
+
after(:each) do
|
79
|
+
VCR::Config.default_cassette_options = @orig_default_options
|
80
|
+
end
|
81
|
+
|
82
|
+
def cassette_body(name, options = {})
|
83
|
+
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
|
84
|
+
VCR::Cassette.new(name, options.merge(:record => :new_episodes)).recorded_interactions.first.response.body
|
85
|
+
end
|
86
|
+
|
87
|
+
it "compiles a template as ERB if the :erb option is passed as true" do
|
88
|
+
cassette_body('erb_with_no_vars', :erb => true).should == 'sum: 3'
|
89
|
+
end
|
90
|
+
|
91
|
+
it "compiles a template as ERB if the default :erb option is true, and no option is passed to the cassette" do
|
92
|
+
VCR::Config.default_cassette_options = { :erb => true }
|
93
|
+
cassette_body('erb_with_no_vars').should == 'sum: 3'
|
94
|
+
end
|
95
|
+
|
96
|
+
it "does not compile a template as ERB if the default :erb option is true, and :erb => false is passed to the cassette" do
|
97
|
+
VCR::Config.default_cassette_options = { :erb => true }
|
98
|
+
cassette_body('erb_with_no_vars', :erb => false).should == 'sum: <%= 1 + 2 %>'
|
99
|
+
end
|
100
|
+
|
101
|
+
it "compiles a template as ERB if the :erb option is passed a hash" do
|
102
|
+
cassette_body('erb_with_vars', :erb => { :var1 => 'a', :var3 => 'c', :var2 => 'b' }).should == 'var1: a; var2: b; var3: c'
|
103
|
+
end
|
104
|
+
|
105
|
+
it "does not compile a template as ERB if the :erb option is not used" do
|
106
|
+
cassette_body('erb_with_no_vars').should == 'sum: <%= 1 + 2 %>'
|
107
|
+
end
|
108
|
+
|
109
|
+
it "raises a helpful error if the ERB template references variables that are not passed in the :erb hash" do
|
110
|
+
expect {
|
111
|
+
cassette_body('erb_with_vars', :erb => { :var1 => 'a', :var2 => 'b' })
|
112
|
+
}.to raise_error(VCR::Cassette::MissingERBVariableError,
|
113
|
+
%{The ERB in the erb_with_vars.yml cassette file references undefined variable var3. } +
|
114
|
+
%{Pass it to the cassette using :erb => #{ { :var1 => 'a', :var2 => 'b' }.merge(:var3 => 'some value').inspect }.}
|
115
|
+
)
|
116
|
+
end
|
117
|
+
|
118
|
+
it "raises a helpful error if the ERB template references variables and :erb => true is passed" do
|
119
|
+
expect {
|
120
|
+
cassette_body('erb_with_vars', :erb => true)
|
121
|
+
}.to raise_error(VCR::Cassette::MissingERBVariableError,
|
122
|
+
%{The ERB in the erb_with_vars.yml cassette file references undefined variable var1. } +
|
123
|
+
%{Pass it to the cassette using :erb => {:var1=>"some value"}.}
|
124
|
+
)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
VCR::Cassette::VALID_RECORD_MODES.each do |record_mode|
|
129
|
+
http_connections_allowed = (record_mode != :none)
|
130
|
+
load_interactions = (record_mode != :all)
|
131
|
+
|
132
|
+
context "when VCR::Config.default_cassette_options[:record] is :#{record_mode}" do
|
133
|
+
before(:each) { VCR::Config.default_cassette_options = { :record => record_mode } }
|
134
|
+
|
135
|
+
it "defaults the record mode to #{record_mode} when VCR::Config.default_cassette_options[:record] is #{record_mode}" do
|
136
|
+
cassette = VCR::Cassette.new(:test)
|
137
|
+
cassette.record_mode.should == record_mode
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context "when the record mode is :#{record_mode}" do
|
142
|
+
it "sets http_connections_allowed to #{http_connections_allowed} on the http stubbing adapter" do
|
143
|
+
VCR.http_stubbing_adapter.should_receive(:http_connections_allowed=).with(http_connections_allowed)
|
144
|
+
VCR::Cassette.new(:name, :record => record_mode)
|
145
|
+
end
|
146
|
+
|
147
|
+
if load_interactions
|
148
|
+
|
149
|
+
[true, false].each do |ignore_localhost|
|
150
|
+
expected_uri_hosts = %w(example.com)
|
151
|
+
expected_uri_hosts += VCR::LOCALHOST_ALIASES unless ignore_localhost
|
152
|
+
|
153
|
+
it "#{ ignore_localhost ? 'does not load' : 'loads' } localhost interactions from the cassette file when http_stubbing_adapter.ignore_localhost is set to #{ignore_localhost}" do
|
154
|
+
VCR.http_stubbing_adapter.stub!(:ignore_localhost?).and_return(ignore_localhost)
|
155
|
+
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
|
156
|
+
cassette = VCR::Cassette.new('with_localhost_requests', :record => record_mode)
|
157
|
+
cassette.recorded_interactions.map { |i| URI.parse(i.uri).host }.should =~ expected_uri_hosts
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
it "loads the recorded interactions from the library yml file" do
|
162
|
+
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
|
163
|
+
cassette = VCR::Cassette.new('example', :record => record_mode)
|
164
|
+
|
165
|
+
cassette.should have(3).recorded_interactions
|
166
|
+
|
167
|
+
i1, i2, i3 = *cassette.recorded_interactions
|
168
|
+
|
169
|
+
i1.request.method.should == :get
|
170
|
+
i1.request.uri.should == 'http://example.com:80/'
|
171
|
+
i1.response.body.should =~ /You have reached this web page by typing.+example\.com/
|
172
|
+
|
173
|
+
i2.request.method.should == :get
|
174
|
+
i2.request.uri.should == 'http://example.com:80/foo'
|
175
|
+
i2.response.body.should =~ /foo was not found on this server/
|
176
|
+
|
177
|
+
i3.request.method.should == :get
|
178
|
+
i3.request.uri.should == 'http://example.com:80/'
|
179
|
+
i3.response.body.should =~ /Another example\.com response/
|
180
|
+
end
|
181
|
+
|
182
|
+
it "stubs the recorded requests with the http stubbing adapter" do
|
183
|
+
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
|
184
|
+
VCR.http_stubbing_adapter.should_receive(:stub_requests).with([an_instance_of(VCR::HTTPInteraction)]*3, anything)
|
185
|
+
cassette = VCR::Cassette.new('example', :record => record_mode)
|
186
|
+
end
|
187
|
+
|
188
|
+
it "passes the :match_request_on option to #stub_requests" do
|
189
|
+
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
|
190
|
+
VCR.http_stubbing_adapter.should_receive(:stub_requests).with(anything, [:body, :headers])
|
191
|
+
cassette = VCR::Cassette.new('example', :record => record_mode, :match_requests_on => [:body, :headers])
|
192
|
+
end
|
193
|
+
|
194
|
+
else
|
195
|
+
|
196
|
+
it "does not stub the recorded requests with the http stubbing adapter" do
|
197
|
+
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
|
198
|
+
VCR.http_stubbing_adapter.should_not_receive(:stub_requests)
|
199
|
+
cassette = VCR::Cassette.new('example', :record => record_mode)
|
200
|
+
end
|
201
|
+
|
202
|
+
it "does not load the recorded interactions from the library yml file" do
|
203
|
+
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
|
204
|
+
cassette = VCR::Cassette.new('example', :record => record_mode)
|
205
|
+
cassette.should have(0).recorded_interactions
|
206
|
+
end
|
207
|
+
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
describe '#eject' do
|
214
|
+
temp_dir File.expand_path(File.dirname(__FILE__) + '/fixtures/cassette_spec_eject'), :assign_to_cassette_library_dir => true
|
215
|
+
|
216
|
+
[true, false].each do |orig_http_connections_allowed|
|
217
|
+
it "resets #{orig_http_connections_allowed} on the http stubbing adapter if it was originally #{orig_http_connections_allowed}" do
|
218
|
+
VCR.http_stubbing_adapter.should_receive(:http_connections_allowed?).and_return(orig_http_connections_allowed)
|
219
|
+
cassette = VCR::Cassette.new(:name)
|
220
|
+
VCR.http_stubbing_adapter.should_receive(:http_connections_allowed=).with(orig_http_connections_allowed)
|
221
|
+
cassette.eject
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
it "writes the recorded interactions to disk as yaml" do
|
226
|
+
recorded_interactions = [
|
227
|
+
VCR::HTTPInteraction.new(:req_sig_1, :response_1),
|
228
|
+
VCR::HTTPInteraction.new(:req_sig_2, :response_2),
|
229
|
+
VCR::HTTPInteraction.new(:req_sig_3, :response_3)
|
230
|
+
]
|
231
|
+
|
232
|
+
cassette = VCR::Cassette.new(:eject_test)
|
233
|
+
cassette.stub!(:recorded_interactions).and_return(recorded_interactions)
|
234
|
+
|
235
|
+
lambda { cassette.eject }.should change { File.exist?(cassette.file) }.from(false).to(true)
|
236
|
+
saved_recorded_interactions = File.open(cassette.file, "r") { |f| YAML.load(f.read) }
|
237
|
+
saved_recorded_interactions.should == recorded_interactions
|
238
|
+
end
|
239
|
+
|
240
|
+
it "writes the recorded interactions to a subdirectory if the cassette name includes a directory" do
|
241
|
+
recorded_interactions = [VCR::HTTPInteraction.new(:the_request, :the_response)]
|
242
|
+
cassette = VCR::Cassette.new('subdirectory/test_cassette')
|
243
|
+
cassette.stub!(:recorded_interactions).and_return(recorded_interactions)
|
244
|
+
|
245
|
+
lambda { cassette.eject }.should change { File.exist?(cassette.file) }.from(false).to(true)
|
246
|
+
saved_recorded_interactions = File.open(cassette.file, "r") { |f| YAML.load(f.read) }
|
247
|
+
saved_recorded_interactions.should == recorded_interactions
|
248
|
+
end
|
249
|
+
|
250
|
+
it "writes both old and new recorded interactions to disk" do
|
251
|
+
file = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec/example.yml")
|
252
|
+
FileUtils.cp file, File.join(@temp_dir, 'previously_recorded_interactions.yml')
|
253
|
+
cassette = VCR::Cassette.new('previously_recorded_interactions')
|
254
|
+
cassette.should have(3).recorded_interactions
|
255
|
+
new_recorded_interaction = VCR::HTTPInteraction.new(:the_request, :the_response)
|
256
|
+
cassette.record_http_interaction(new_recorded_interaction)
|
257
|
+
cassette.eject
|
258
|
+
saved_recorded_interactions = File.open(cassette.file, "r") { |f| YAML.load(f.read) }
|
259
|
+
saved_recorded_interactions.should have(4).recorded_interactions
|
260
|
+
saved_recorded_interactions.last.should == new_recorded_interaction
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
describe '#eject for a cassette with previously recorded interactions' do
|
265
|
+
it "restore the stubs checkpoint on the http stubbing adapter" do
|
266
|
+
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
|
267
|
+
cassette = VCR::Cassette.new('example', :record => :none)
|
268
|
+
VCR.http_stubbing_adapter.should_receive(:restore_stubs_checkpoint).with('example')
|
269
|
+
cassette.eject
|
270
|
+
end
|
271
|
+
|
272
|
+
it "does not re-write to disk the previously recorded interactions if there are no new ones" do
|
273
|
+
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
|
274
|
+
yaml_file = File.join(VCR::Config.cassette_library_dir, 'example.yml')
|
275
|
+
cassette = VCR::Cassette.new('example', :record => :none)
|
276
|
+
File.should_not_receive(:open).with(cassette.file, 'w')
|
277
|
+
lambda { cassette.eject }.should_not change { File.mtime(yaml_file) }
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|