vcr 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +5 -0
- data/VERSION +1 -1
- data/features/support/env.rb +3 -0
- data/lib/vcr.rb +1 -0
- data/lib/vcr/extensions/net_http.rb +1 -0
- data/lib/vcr/extensions/net_http_response.rb +48 -0
- data/spec/extensions/net_http_response_spec.rb +86 -0
- data/vcr.gemspec +5 -2
- metadata +6 -3
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
#Changelog
|
2
2
|
|
3
|
+
## 0.4.1 May 11, 2010
|
4
|
+
* Fixed a bug: when `Net::HTTPResponse#read_body` was called after VCR had read the body to record a new request,
|
5
|
+
it raised an error (`IOError: Net::HTTPResponse#read_body called twice`). My fix extends Net::HTTPResponse
|
6
|
+
so that it no longer raises this error.
|
7
|
+
|
3
8
|
## 0.4.0 April 28, 2010
|
4
9
|
* Added support for webmock. All the fakeweb-specific code is now in an adapter (as is the webmock code).
|
5
10
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.1
|
data/features/support/env.rb
CHANGED
@@ -32,6 +32,9 @@ VCR.module_eval do
|
|
32
32
|
end
|
33
33
|
|
34
34
|
After do |scenario|
|
35
|
+
if raised_error = (@http_requests || {}).values.flatten.detect { |result| result.is_a?(Exception) && result.message !~ /VCR/ }
|
36
|
+
raise raised_error
|
37
|
+
end
|
35
38
|
VCR.completed_cucumber_scenarios << scenario
|
36
39
|
end
|
37
40
|
|
data/lib/vcr.rb
CHANGED
@@ -0,0 +1,48 @@
|
|
1
|
+
# A Net::HTTP response that has already been read raises an IOError when #read_body
|
2
|
+
# is called with a destination string or block.
|
3
|
+
#
|
4
|
+
# This causes a problem when VCR records a response--it reads the body before yielding
|
5
|
+
# the response, and if the code that is consuming the HTTP requests uses #read_body, it
|
6
|
+
# can cause an error.
|
7
|
+
#
|
8
|
+
# This is a bit of a hack, but it allows a Net::HTTP response to be "re-read"
|
9
|
+
# after it has aleady been read. This attemps to preserve the behavior of
|
10
|
+
# #read_body, acting just as if it had never been read.
|
11
|
+
|
12
|
+
module VCR
|
13
|
+
module Net
|
14
|
+
module HTTPResponse
|
15
|
+
def self.extended(object)
|
16
|
+
body_object = object.instance_variable_get(:@body)
|
17
|
+
object.instance_variable_set(:@__orig_body__,
|
18
|
+
case body_object
|
19
|
+
when String then body_object
|
20
|
+
when ::Net::ReadAdapter then body_object.instance_variable_get(:@__body_for_vcr__)
|
21
|
+
else raise ArgumentError.new("Unexpected body object: #{body_object}")
|
22
|
+
end
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
def read_body(dest = nil, &block)
|
27
|
+
if @__orig_body__
|
28
|
+
if dest && block
|
29
|
+
raise ArgumentError.new("both arg and block given for HTTP method")
|
30
|
+
elsif dest
|
31
|
+
dest << @__orig_body__
|
32
|
+
elsif block
|
33
|
+
@body = ::Net::ReadAdapter.new(block)
|
34
|
+
@body << @__orig_body__
|
35
|
+
@body
|
36
|
+
else
|
37
|
+
@body = @__orig_body__
|
38
|
+
end
|
39
|
+
else
|
40
|
+
super
|
41
|
+
end
|
42
|
+
ensure
|
43
|
+
# allow subsequent calls to #read_body to proceed as normal, without our hack...
|
44
|
+
@__orig_body__ = nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe "Net::HTTP Response extensions" do
|
4
|
+
context 'extending an already read response' do
|
5
|
+
# disable VCR for this spec...
|
6
|
+
before(:each) { VCR.insert_cassette('response_extension', :allow_real_http => lambda { |uri| true }) }
|
7
|
+
after(:each) { VCR.eject_cassette }
|
8
|
+
|
9
|
+
def self.it_allows_the_body_to_be_read_again
|
10
|
+
let(:expected_regex) { /You have reached this web page by typing.*example\.com/ }
|
11
|
+
|
12
|
+
it 'allows the body to be read using #body' do
|
13
|
+
subject.body.to_s.should =~ expected_regex
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'allows the body to be read using #read_body' do
|
17
|
+
subject.read_body.to_s.should =~ expected_regex
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'allows the body to be read using #read_body with a block' do
|
21
|
+
yielded_body = ''
|
22
|
+
ret_val = subject.read_body { |s| yielded_body << s }
|
23
|
+
yielded_body.should =~ expected_regex
|
24
|
+
ret_val.should be_instance_of(Net::ReadAdapter)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'allows the body to be read by passing a destination string to #read_body' do
|
28
|
+
dest = ''
|
29
|
+
ret_val = subject.read_body(dest)
|
30
|
+
dest.should =~ expected_regex
|
31
|
+
ret_val.should == dest
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'raises an ArgumentError if both a destination string and a block is given to #read_body' do
|
35
|
+
dest = ''
|
36
|
+
expect { subject.read_body(dest) { |s| } }.should raise_error(ArgumentError, 'both arg and block given for HTTP method')
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'raises an IOError when #read_body is called twice with a block' do
|
40
|
+
subject.read_body { |s| }
|
41
|
+
expect { subject.read_body { |s| } }.to raise_error(IOError, /read_body called twice/)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'raises an IOError when #read_body is called twice with a destination string' do
|
45
|
+
dest = ''
|
46
|
+
subject.read_body(dest)
|
47
|
+
expect { subject.read_body(dest) }.to raise_error(IOError, /read_body called twice/)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'when the body has already been read using #read_body and a block' do
|
52
|
+
subject do
|
53
|
+
http = Net::HTTP.new('example.com', 80)
|
54
|
+
response = http.request_get('/') { |res| res.read_body { |s| } }
|
55
|
+
response.extend VCR::Net::HTTPResponse
|
56
|
+
response
|
57
|
+
end
|
58
|
+
|
59
|
+
it_allows_the_body_to_be_read_again
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'when the body has already been read using #read_body and a dest string' do
|
63
|
+
subject do
|
64
|
+
http = Net::HTTP.new('example.com', 80)
|
65
|
+
dest = ''
|
66
|
+
response = http.request_get('/') { |res| res.read_body(dest) }
|
67
|
+
response.extend VCR::Net::HTTPResponse
|
68
|
+
response
|
69
|
+
end
|
70
|
+
|
71
|
+
it_allows_the_body_to_be_read_again
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'when the body has already been read using #body' do
|
75
|
+
subject do
|
76
|
+
http = Net::HTTP.new('example.com', 80)
|
77
|
+
response = http.request_get('/')
|
78
|
+
response.body
|
79
|
+
response.extend VCR::Net::HTTPResponse
|
80
|
+
response
|
81
|
+
end
|
82
|
+
|
83
|
+
it_allows_the_body_to_be_read_again
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/vcr.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{vcr}
|
8
|
-
s.version = "0.4.
|
8
|
+
s.version = "0.4.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Myron Marston"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-05-11}
|
13
13
|
s.description = %q{VCR provides helpers to record your test suite's HTTP interactions and replay them during future test runs for fast, deterministic, accurate tests. It works with any ruby testing framework, and provides built-in support for cucumber.}
|
14
14
|
s.email = %q{myron.marston@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -51,6 +51,7 @@ Gem::Specification.new do |s|
|
|
51
51
|
"lib/vcr/deprecations.rb",
|
52
52
|
"lib/vcr/extensions/fake_web.rb",
|
53
53
|
"lib/vcr/extensions/net_http.rb",
|
54
|
+
"lib/vcr/extensions/net_http_response.rb",
|
54
55
|
"lib/vcr/extensions/net_read_adapter.rb",
|
55
56
|
"lib/vcr/http_stubbing_adapters/base.rb",
|
56
57
|
"lib/vcr/http_stubbing_adapters/fakeweb.rb",
|
@@ -62,6 +63,7 @@ Gem::Specification.new do |s|
|
|
62
63
|
"spec/config_spec.rb",
|
63
64
|
"spec/cucumber_tags_spec.rb",
|
64
65
|
"spec/deprecations_spec.rb",
|
66
|
+
"spec/extensions/net_http_response_spec.rb",
|
65
67
|
"spec/extensions/net_http_spec.rb",
|
66
68
|
"spec/extensions/net_read_adapter_spec.rb",
|
67
69
|
"spec/fixtures/1.8.6/0_3_1_cassette.yml",
|
@@ -105,6 +107,7 @@ Gem::Specification.new do |s|
|
|
105
107
|
"spec/config_spec.rb",
|
106
108
|
"spec/cucumber_tags_spec.rb",
|
107
109
|
"spec/deprecations_spec.rb",
|
110
|
+
"spec/extensions/net_http_response_spec.rb",
|
108
111
|
"spec/extensions/net_http_spec.rb",
|
109
112
|
"spec/extensions/net_read_adapter_spec.rb",
|
110
113
|
"spec/http_stubbing_adapters/fakeweb_spec.rb",
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 4
|
8
|
-
-
|
9
|
-
version: 0.4.
|
8
|
+
- 1
|
9
|
+
version: 0.4.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Myron Marston
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-05-11 00:00:00 -07:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -117,6 +117,7 @@ files:
|
|
117
117
|
- lib/vcr/deprecations.rb
|
118
118
|
- lib/vcr/extensions/fake_web.rb
|
119
119
|
- lib/vcr/extensions/net_http.rb
|
120
|
+
- lib/vcr/extensions/net_http_response.rb
|
120
121
|
- lib/vcr/extensions/net_read_adapter.rb
|
121
122
|
- lib/vcr/http_stubbing_adapters/base.rb
|
122
123
|
- lib/vcr/http_stubbing_adapters/fakeweb.rb
|
@@ -128,6 +129,7 @@ files:
|
|
128
129
|
- spec/config_spec.rb
|
129
130
|
- spec/cucumber_tags_spec.rb
|
130
131
|
- spec/deprecations_spec.rb
|
132
|
+
- spec/extensions/net_http_response_spec.rb
|
131
133
|
- spec/extensions/net_http_spec.rb
|
132
134
|
- spec/extensions/net_read_adapter_spec.rb
|
133
135
|
- spec/fixtures/1.8.6/0_3_1_cassette.yml
|
@@ -195,6 +197,7 @@ test_files:
|
|
195
197
|
- spec/config_spec.rb
|
196
198
|
- spec/cucumber_tags_spec.rb
|
197
199
|
- spec/deprecations_spec.rb
|
200
|
+
- spec/extensions/net_http_response_spec.rb
|
198
201
|
- spec/extensions/net_http_spec.rb
|
199
202
|
- spec/extensions/net_read_adapter_spec.rb
|
200
203
|
- spec/http_stubbing_adapters/fakeweb_spec.rb
|