vcr 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +62 -0
- data/README.md +224 -0
- data/Rakefile +12 -5
- data/VERSION +1 -1
- data/benchmarks/http_stubbing_libraries.rb +59 -0
- data/features/fixtures/vcr_cassettes/1.8.6/cucumber_tags/replay_cassette1.yml +25 -25
- data/features/fixtures/vcr_cassettes/1.8.6/cucumber_tags/replay_cassette2.yml +32 -30
- data/features/fixtures/vcr_cassettes/1.8.6/cucumber_tags/replay_cassette3.yml +40 -40
- data/features/fixtures/vcr_cassettes/1.8.6/nested_replay_cassette.yml +16 -15
- data/features/fixtures/vcr_cassettes/1.8.6/not_the_real_response.yml +25 -25
- data/features/fixtures/vcr_cassettes/1.8.7/cucumber_tags/replay_cassette1.yml +23 -23
- data/features/fixtures/vcr_cassettes/1.8.7/cucumber_tags/replay_cassette2.yml +24 -22
- data/features/fixtures/vcr_cassettes/1.8.7/cucumber_tags/replay_cassette3.yml +36 -36
- data/features/fixtures/vcr_cassettes/1.8.7/nested_replay_cassette.yml +12 -11
- data/features/fixtures/vcr_cassettes/1.8.7/not_the_real_response.yml +23 -23
- data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette1.yml +24 -24
- data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette2.yml +26 -24
- data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette3.yml +38 -38
- data/features/fixtures/vcr_cassettes/1.9.1/nested_replay_cassette.yml +13 -12
- data/features/fixtures/vcr_cassettes/1.9.1/not_the_real_response.yml +24 -24
- data/features/record_response.feature +2 -2
- data/features/replay_recorded_response.feature +1 -1
- data/features/step_definitions/vcr_steps.rb +8 -8
- data/features/support/env.rb +6 -0
- data/lib/vcr.rb +16 -3
- data/lib/vcr/cassette.rb +49 -46
- data/lib/vcr/config.rb +8 -0
- data/lib/vcr/extensions/fake_web.rb +12 -26
- data/lib/vcr/extensions/net_http.rb +9 -26
- data/lib/vcr/http_stubbing_adapters/base.rb +34 -0
- data/lib/vcr/http_stubbing_adapters/fakeweb.rb +75 -0
- data/lib/vcr/http_stubbing_adapters/webmock.rb +80 -0
- data/lib/vcr/structs.rb +44 -0
- data/lib/vcr/task_runner.rb +47 -0
- data/lib/vcr/tasks/vcr.rake +9 -0
- data/spec/cassette_spec.rb +70 -71
- data/spec/config_spec.rb +27 -0
- data/spec/extensions/net_http_spec.rb +21 -17
- data/spec/fixtures/1.8.6/0_3_1_cassette.yml +29 -0
- data/spec/fixtures/1.8.6/cassette_spec/example.yml +110 -108
- data/spec/fixtures/1.8.6/example_net_http.yml +14 -0
- data/spec/fixtures/1.8.6/example_net_http_request.yml +12 -0
- data/spec/fixtures/1.8.6/example_net_http_response.yml +25 -0
- data/spec/fixtures/1.8.6/fake_example.com_responses.yml +90 -0
- data/spec/fixtures/1.8.7/0_3_1_cassette.yml +29 -0
- data/spec/fixtures/1.8.7/cassette_spec/example.yml +110 -108
- data/spec/fixtures/1.8.7/example_net_http.yml +14 -0
- data/spec/fixtures/1.8.7/example_net_http_request.yml +12 -0
- data/spec/fixtures/1.8.7/example_net_http_response.yml +25 -0
- data/spec/fixtures/1.8.7/fake_example.com_responses.yml +90 -0
- data/spec/fixtures/1.9.1/0_3_1_cassette.yml +29 -0
- data/spec/fixtures/1.9.1/cassette_spec/example.yml +62 -59
- 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 +90 -0
- data/spec/http_stubbing_adapters/fakeweb_spec.rb +24 -0
- data/spec/http_stubbing_adapters/webmock_spec.rb +23 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/structs_spec.rb +95 -0
- data/spec/support/http_stubbing_adapter.rb +113 -0
- data/spec/task_runner_spec.rb +59 -0
- data/spec/vcr_spec.rb +37 -0
- data/vcr.gemspec +45 -15
- metadata +67 -26
- data/History.rdoc +0 -31
- data/README.rdoc +0 -222
- data/lib/vcr/recorded_response.rb +0 -4
- data/spec/extensions/fake_web_spec.rb +0 -63
- data/spec/recorded_response_spec.rb +0 -25
data/features/support/env.rb
CHANGED
@@ -13,6 +13,12 @@ require 'spec/expectations'
|
|
13
13
|
|
14
14
|
VCR.config do |c|
|
15
15
|
c.cassette_library_dir = File.join(File.dirname(__FILE__), '..', 'fixtures', 'vcr_cassettes', RUBY_VERSION)
|
16
|
+
c.http_stubbing_library = if ENV['HTTP_STUBBING_ADAPTER'].to_s == ''
|
17
|
+
warn "Using fakeweb for VCR's cucumber features since the adapter was not specified. Set HTTP_STUBBING_ADAPTER to specify."
|
18
|
+
:fakeweb
|
19
|
+
else
|
20
|
+
ENV['HTTP_STUBBING_ADAPTER'].to_sym
|
21
|
+
end
|
16
22
|
end
|
17
23
|
|
18
24
|
VCR.module_eval do
|
data/lib/vcr.rb
CHANGED
@@ -2,12 +2,12 @@ require 'vcr/cassette'
|
|
2
2
|
require 'vcr/config'
|
3
3
|
require 'vcr/cucumber_tags'
|
4
4
|
require 'vcr/deprecations'
|
5
|
-
require 'vcr/
|
5
|
+
require 'vcr/structs'
|
6
6
|
|
7
|
-
require 'vcr/extensions/fake_web'
|
8
|
-
require 'vcr/extensions/net_http'
|
9
7
|
require 'vcr/extensions/net_read_adapter'
|
10
8
|
|
9
|
+
require 'vcr/http_stubbing_adapters/base'
|
10
|
+
|
11
11
|
module VCR
|
12
12
|
extend self
|
13
13
|
|
@@ -36,6 +36,8 @@ module VCR
|
|
36
36
|
|
37
37
|
def config
|
38
38
|
yield VCR::Config
|
39
|
+
http_stubbing_adapter.check_version!
|
40
|
+
http_stubbing_adapter.http_connections_allowed = false
|
39
41
|
end
|
40
42
|
|
41
43
|
def cucumber_tags(&block)
|
@@ -43,6 +45,17 @@ module VCR
|
|
43
45
|
yield VCR::CucumberTags.new(main_object)
|
44
46
|
end
|
45
47
|
|
48
|
+
def http_stubbing_adapter
|
49
|
+
@http_stubbing_adapter ||= case VCR::Config.http_stubbing_library
|
50
|
+
when :fakeweb
|
51
|
+
VCR::HttpStubbingAdapters::FakeWeb
|
52
|
+
when :webmock
|
53
|
+
VCR::HttpStubbingAdapters::WebMock
|
54
|
+
else
|
55
|
+
raise ArgumentError.new("The http stubbing library is not configured correctly. You should set it to :webmock or :fakeweb.")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
46
59
|
private
|
47
60
|
|
48
61
|
def cassettes
|
data/lib/vcr/cassette.rb
CHANGED
@@ -10,92 +10,95 @@ module VCR
|
|
10
10
|
def initialize(name, options = {})
|
11
11
|
@name = name
|
12
12
|
@record_mode = options[:record] || VCR::Config.default_cassette_options[:record]
|
13
|
-
deprecate_unregistered_record_mode
|
14
13
|
@allow_real_http_lambda = allow_real_http_lambda_for(options[:allow_real_http] || VCR::Config.default_cassette_options[:allow_real_http])
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
|
15
|
+
deprecate_unregistered_record_mode
|
16
|
+
raise_error_unless_valid_record_mode(record_mode)
|
17
|
+
|
18
|
+
set_http_connections_allowed
|
19
|
+
load_recorded_interactions
|
18
20
|
end
|
19
21
|
|
20
22
|
def eject
|
21
|
-
|
22
|
-
|
23
|
-
|
23
|
+
write_recorded_interactions_to_disk
|
24
|
+
VCR.http_stubbing_adapter.restore_stubs_checkpoint(name)
|
25
|
+
restore_http_connections_allowed
|
24
26
|
end
|
25
27
|
|
26
|
-
def
|
27
|
-
@
|
28
|
+
def recorded_interactions
|
29
|
+
@recorded_interactions ||= []
|
28
30
|
end
|
29
31
|
|
30
|
-
def
|
31
|
-
|
32
|
+
def record_http_interaction(interaction)
|
33
|
+
recorded_interactions << interaction
|
32
34
|
end
|
33
35
|
|
34
36
|
def file
|
35
37
|
File.join(VCR::Config.cassette_library_dir, "#{name.to_s.gsub(/[^\w\-\/]+/, '_')}.yml") if VCR::Config.cassette_library_dir
|
36
38
|
end
|
37
39
|
|
38
|
-
def
|
40
|
+
def allow_real_http_requests_to?(uri)
|
41
|
+
@allow_real_http_lambda ? @allow_real_http_lambda.call(uri) : false
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def raise_error_unless_valid_record_mode(record_mode)
|
39
47
|
unless VALID_RECORD_MODES.include?(record_mode)
|
40
48
|
raise ArgumentError.new("#{record_mode} is not a valid cassette record mode. Valid options are: #{VALID_RECORD_MODES.inspect}")
|
41
49
|
end
|
42
50
|
end
|
43
51
|
|
44
|
-
def
|
45
|
-
|
52
|
+
def new_recorded_interactions
|
53
|
+
recorded_interactions - @original_recorded_interactions
|
46
54
|
end
|
47
55
|
|
48
|
-
def
|
49
|
-
recorded_responses - @original_recorded_responses
|
50
|
-
end
|
51
|
-
|
52
|
-
def should_allow_net_connect?
|
56
|
+
def should_allow_http_connections?
|
53
57
|
[:new_episodes, :all].include?(record_mode)
|
54
58
|
end
|
55
59
|
|
56
|
-
def
|
57
|
-
@
|
58
|
-
|
60
|
+
def set_http_connections_allowed
|
61
|
+
@orig_http_connections_allowed = VCR.http_stubbing_adapter.http_connections_allowed?
|
62
|
+
VCR.http_stubbing_adapter.http_connections_allowed = should_allow_http_connections?
|
59
63
|
end
|
60
64
|
|
61
|
-
def
|
62
|
-
|
65
|
+
def restore_http_connections_allowed
|
66
|
+
VCR.http_stubbing_adapter.http_connections_allowed = @orig_http_connections_allowed
|
63
67
|
end
|
64
68
|
|
65
|
-
def
|
66
|
-
|
69
|
+
def load_recorded_interactions
|
70
|
+
VCR.http_stubbing_adapter.create_stubs_checkpoint(name)
|
71
|
+
@original_recorded_interactions = []
|
67
72
|
return if record_mode == :all
|
68
73
|
|
69
74
|
if file
|
70
|
-
@
|
71
|
-
|
75
|
+
@original_recorded_interactions = begin
|
76
|
+
yaml_content = File.read(file)
|
77
|
+
YAML.load(yaml_content)
|
78
|
+
rescue TypeError
|
79
|
+
if yaml_content =~ /VCR::RecordedResponse/
|
80
|
+
raise "The VCR cassette #{name} uses an old format that is now deprecated. VCR provides a rake task to migrate your old cassettes to the new format. See http://github.com/myronmarston/vcr/blob/master/CHANGELOG.md for more info."
|
81
|
+
else
|
82
|
+
raise
|
83
|
+
end
|
84
|
+
end if File.exist?(file)
|
85
|
+
|
86
|
+
recorded_interactions.replace(@original_recorded_interactions)
|
72
87
|
end
|
73
88
|
|
74
|
-
|
89
|
+
VCR.http_stubbing_adapter.stub_requests(recorded_interactions)
|
75
90
|
end
|
76
91
|
|
77
|
-
def
|
78
|
-
|
79
|
-
recorded_responses.each do |rr|
|
80
|
-
requests[[rr.method, rr.uri]] += [rr.response]
|
81
|
-
end
|
82
|
-
requests.each do |request, responses|
|
83
|
-
FakeWeb.register_uri(request.first, request.last, responses.map{ |r| { :response => r } })
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def write_recorded_responses_to_disk
|
88
|
-
if VCR::Config.cassette_library_dir && new_recorded_responses.size > 0
|
92
|
+
def write_recorded_interactions_to_disk
|
93
|
+
if VCR::Config.cassette_library_dir && new_recorded_interactions.size > 0
|
89
94
|
directory = File.dirname(file)
|
90
95
|
FileUtils.mkdir_p directory unless File.exist?(directory)
|
91
|
-
File.open(file, 'w') { |f| f.write
|
96
|
+
File.open(file, 'w') { |f| f.write recorded_interactions.to_yaml }
|
92
97
|
end
|
93
98
|
end
|
94
99
|
|
95
|
-
def
|
96
|
-
@
|
97
|
-
FakeWeb.remove_from_registry(rr.method, rr.uri)
|
98
|
-
end
|
100
|
+
def unstub_requests
|
101
|
+
VCR.http_stubbing_adapter.unstub_requests(@original_recorded_interactions)
|
99
102
|
end
|
100
103
|
|
101
104
|
def allow_real_http_lambda_for(allow_option)
|
data/lib/vcr/config.rb
CHANGED
@@ -13,6 +13,14 @@ module VCR
|
|
13
13
|
def default_cassette_options
|
14
14
|
@default_cassette_options ||= {}
|
15
15
|
end
|
16
|
+
|
17
|
+
attr_writer :http_stubbing_library
|
18
|
+
def http_stubbing_library
|
19
|
+
@http_stubbing_library ||= begin
|
20
|
+
defined_constants = [:FakeWeb, :WebMock].select { |c| Object.const_defined?(c) }
|
21
|
+
defined_constants[0].to_s.downcase.to_sym if defined_constants.size == 1
|
22
|
+
end
|
23
|
+
end
|
16
24
|
end
|
17
25
|
end
|
18
26
|
end
|
@@ -1,34 +1,20 @@
|
|
1
|
-
require '
|
1
|
+
require 'fakeweb'
|
2
2
|
|
3
3
|
module FakeWeb
|
4
|
-
def self.
|
5
|
-
|
6
|
-
|
4
|
+
def self.request_uri(net_http, request)
|
5
|
+
# Copied from: http://github.com/chrisk/fakeweb/blob/fakeweb-1.2.8/lib/fake_web/ext/net_http.rb#L39-52
|
6
|
+
protocol = net_http.use_ssl? ? "https" : "http"
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
begin
|
11
|
-
FakeWeb.allow_net_connect = value
|
12
|
-
yield
|
13
|
-
ensure
|
14
|
-
FakeWeb.allow_net_connect = original_value
|
15
|
-
end
|
16
|
-
end
|
8
|
+
path = request.path
|
9
|
+
path = URI.parse(request.path).request_uri if request.path =~ /^http/
|
17
10
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
method_hash.empty? # there's no point in keeping this entry in the uri map if its method hash is empty...
|
24
|
-
end
|
25
|
-
end
|
11
|
+
if request["authorization"] =~ /^Basic /
|
12
|
+
userinfo = FakeWeb::Utility.decode_userinfo_from_header(request["authorization"])
|
13
|
+
userinfo = FakeWeb::Utility.encode_unsafe_chars_in_userinfo(userinfo) + "@"
|
14
|
+
else
|
15
|
+
userinfo = ""
|
26
16
|
end
|
27
|
-
end
|
28
17
|
|
29
|
-
|
30
|
-
def message
|
31
|
-
super + '. You can use VCR to automatically record this request and replay it later with fakeweb. For more details, see the VCR README at: http://github.com/myronmarston/vcr'
|
32
|
-
end
|
18
|
+
"#{protocol}://#{userinfo}#{net_http.address}:#{net_http.port}#{path}"
|
33
19
|
end
|
34
20
|
end
|
@@ -3,48 +3,31 @@ require 'net/http'
|
|
3
3
|
module Net
|
4
4
|
class HTTP
|
5
5
|
def request_with_vcr(request, body = nil, &block)
|
6
|
-
|
7
|
-
|
6
|
+
uri = URI.parse(VCR.http_stubbing_adapter.request_uri(self, request))
|
7
|
+
|
8
8
|
if (cassette = VCR.current_cassette) && cassette.allow_real_http_requests_to?(uri)
|
9
|
-
|
9
|
+
VCR.http_stubbing_adapter.with_http_connections_allowed_set_to(true) do
|
10
|
+
request_without_vcr(request, body, &block)
|
11
|
+
end
|
10
12
|
else
|
11
13
|
response = request_without_vcr(request, body)
|
12
|
-
__store_response_with_vcr__(response, request) if
|
14
|
+
__store_response_with_vcr__(response, request) if started?
|
13
15
|
yield response if block_given?
|
14
16
|
response
|
15
17
|
end
|
16
|
-
ensure
|
17
|
-
@__request_with_vcr_call_count -= 1
|
18
18
|
end
|
19
19
|
alias_method :request_without_vcr, :request
|
20
20
|
alias_method :request, :request_with_vcr
|
21
21
|
|
22
22
|
private
|
23
23
|
|
24
|
-
def __vcr_uri__(request)
|
25
|
-
# Copied from: http://github.com/chrisk/fakeweb/blob/fakeweb-1.2.8/lib/fake_web/ext/net_http.rb#L39-52
|
26
|
-
protocol = use_ssl? ? "https" : "http"
|
27
|
-
|
28
|
-
path = request.path
|
29
|
-
path = URI.parse(request.path).request_uri if request.path =~ /^http/
|
30
|
-
|
31
|
-
if request["authorization"] =~ /^Basic /
|
32
|
-
userinfo = FakeWeb::Utility.decode_userinfo_from_header(request["authorization"])
|
33
|
-
userinfo = FakeWeb::Utility.encode_unsafe_chars_in_userinfo(userinfo) + "@"
|
34
|
-
else
|
35
|
-
userinfo = ""
|
36
|
-
end
|
37
|
-
|
38
|
-
"#{protocol}://#{userinfo}#{self.address}:#{self.port}#{path}"
|
39
|
-
end
|
40
|
-
|
41
24
|
def __store_response_with_vcr__(response, request)
|
42
25
|
if cassette = VCR.current_cassette
|
43
|
-
uri =
|
26
|
+
uri = VCR.http_stubbing_adapter.request_uri(self, request)
|
44
27
|
method = request.method.downcase.to_sym
|
45
28
|
|
46
|
-
unless
|
47
|
-
cassette.
|
29
|
+
unless VCR.http_stubbing_adapter.request_stubbed?(method, uri)
|
30
|
+
cassette.record_http_interaction(VCR::HTTPInteraction.from_net_http_objects(self, request, response))
|
48
31
|
end
|
49
32
|
end
|
50
33
|
end
|
@@ -0,0 +1,34 @@
|
|
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 Base
|
7
|
+
class << self
|
8
|
+
def with_http_connections_allowed_set_to(value)
|
9
|
+
original_value = http_connections_allowed?
|
10
|
+
self.http_connections_allowed = value
|
11
|
+
begin
|
12
|
+
yield
|
13
|
+
ensure
|
14
|
+
self.http_connections_allowed = original_value
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def meets_version_requirement?(version, required_version)
|
19
|
+
major, minor, patch = *version.split('.').map { |v| v.to_i }
|
20
|
+
req_major, req_minor, req_patch = *required_version.split('.').map { |v| v.to_i }
|
21
|
+
|
22
|
+
return false if major < req_major
|
23
|
+
return true if major > req_major
|
24
|
+
|
25
|
+
return false if minor < req_minor
|
26
|
+
return true if minor > req_minor
|
27
|
+
|
28
|
+
patch >= req_patch
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'vcr/extensions/fake_web'
|
2
|
+
require 'vcr/extensions/net_http'
|
3
|
+
|
4
|
+
module VCR
|
5
|
+
module HttpStubbingAdapters
|
6
|
+
class FakeWeb < Base
|
7
|
+
class << self
|
8
|
+
def check_version!
|
9
|
+
unless meets_version_requirement?(::FakeWeb::VERSION, '1.2.8')
|
10
|
+
raise "You are using FakeWeb #{::FakeWeb::VERSION}. VCR requires version 1.2.8 or greater."
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def http_connections_allowed?
|
15
|
+
::FakeWeb.allow_net_connect?
|
16
|
+
end
|
17
|
+
|
18
|
+
def http_connections_allowed=(value)
|
19
|
+
::FakeWeb.allow_net_connect = value
|
20
|
+
end
|
21
|
+
|
22
|
+
def stub_requests(http_interactions)
|
23
|
+
requests = Hash.new([])
|
24
|
+
|
25
|
+
http_interactions.each do |i|
|
26
|
+
requests[[i.request.method, i.request.uri]] += [i.response]
|
27
|
+
end
|
28
|
+
|
29
|
+
requests.each do |request, responses|
|
30
|
+
::FakeWeb.register_uri(request.first, request.last, responses.map{ |r| response_hash(r) })
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def create_stubs_checkpoint(checkpoint_name)
|
35
|
+
checkpoints[checkpoint_name] = ::FakeWeb::Registry.instance.uri_map.dup
|
36
|
+
end
|
37
|
+
|
38
|
+
def restore_stubs_checkpoint(checkpoint_name)
|
39
|
+
::FakeWeb::Registry.instance.uri_map = checkpoints.delete(checkpoint_name)
|
40
|
+
end
|
41
|
+
|
42
|
+
def request_stubbed?(method, uri)
|
43
|
+
::FakeWeb.registered_uri?(method, uri)
|
44
|
+
end
|
45
|
+
|
46
|
+
def request_uri(net_http, request)
|
47
|
+
::FakeWeb.request_uri(net_http, request)
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def checkpoints
|
53
|
+
@checkpoints ||= {}
|
54
|
+
end
|
55
|
+
|
56
|
+
def response_hash(response)
|
57
|
+
response.headers.merge(
|
58
|
+
:body => response.body,
|
59
|
+
:status => [response.status.code.to_s, response.status.message]
|
60
|
+
)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
if defined?(FakeWeb::NetConnectNotAllowedError)
|
68
|
+
module FakeWeb
|
69
|
+
class NetConnectNotAllowedError
|
70
|
+
def message
|
71
|
+
super + '. You can use VCR to automatically record this request and replay it later. For more details, see the VCR README at: http://github.com/myronmarston/vcr'
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'webmock'
|
2
|
+
require 'vcr/extensions/net_http'
|
3
|
+
|
4
|
+
module VCR
|
5
|
+
module HttpStubbingAdapters
|
6
|
+
class WebMock < Base
|
7
|
+
class << self
|
8
|
+
VERSION_REQUIREMENT = '1.1.0'
|
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
|
15
|
+
|
16
|
+
def http_connections_allowed?
|
17
|
+
::WebMock::Config.instance.allow_net_connect
|
18
|
+
end
|
19
|
+
|
20
|
+
def http_connections_allowed=(value)
|
21
|
+
::WebMock::Config.instance.allow_net_connect = value
|
22
|
+
end
|
23
|
+
|
24
|
+
def stub_requests(recorded_responses)
|
25
|
+
requests = Hash.new([])
|
26
|
+
|
27
|
+
# TODO: use the entire request signature, but make it configurable.
|
28
|
+
recorded_responses.each do |rr|
|
29
|
+
requests[[rr.method, rr.uri]] += [rr.response]
|
30
|
+
end
|
31
|
+
|
32
|
+
requests.each do |request, responses|
|
33
|
+
::WebMock.stub_request(request.first, request.last).
|
34
|
+
to_return(responses.map{ |r| response_hash(r) })
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def create_stubs_checkpoint(checkpoint_name)
|
39
|
+
checkpoints[checkpoint_name] = ::WebMock::RequestRegistry.instance.request_stubs.dup
|
40
|
+
end
|
41
|
+
|
42
|
+
def restore_stubs_checkpoint(checkpoint_name)
|
43
|
+
::WebMock::RequestRegistry.instance.request_stubs = checkpoints.delete(checkpoint_name)
|
44
|
+
end
|
45
|
+
|
46
|
+
def request_stubbed?(method, uri)
|
47
|
+
!!::WebMock.registered_request?(::WebMock::RequestSignature.new(method, uri))
|
48
|
+
end
|
49
|
+
|
50
|
+
def request_uri(net_http, request)
|
51
|
+
::WebMock::NetHTTPUtility.request_signature_from_request(net_http, request).uri.to_s
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def response_hash(response)
|
57
|
+
{
|
58
|
+
:body => response.body,
|
59
|
+
:status => [response.status.code.to_i, response.status.message],
|
60
|
+
:headers => response.headers
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
def checkpoints
|
65
|
+
@checkpoints ||= {}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
if defined?(WebMock::NetConnectNotAllowedError)
|
73
|
+
module WebMock
|
74
|
+
class NetConnectNotAllowedError
|
75
|
+
def message
|
76
|
+
super + '. You can use VCR to automatically record this request and replay it later. For more details, see the VCR README at: http://github.com/myronmarston/vcr'
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|