vcr 1.1.2 → 1.2.0
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/.gitignore +1 -1
- data/.gitmodules +3 -0
- data/CHANGELOG.md +58 -1
- data/Gemfile +2 -4
- data/Gemfile.lock +26 -49
- data/README.md +92 -23
- data/Rakefile +6 -3
- data/features/fixtures/vcr_cassettes/1.9.1/record_all.yml +62 -0
- data/features/fixtures/vcr_cassettes/not_1.9.1/record_all.yml +61 -0
- data/features/http_client.feature +2 -2
- data/features/net_http.feature +15 -4
- data/features/record_response.feature +36 -7
- data/features/replay_recorded_response.feature +8 -8
- data/features/rspec.feature +100 -0
- data/features/step_definitions/net_http_steps.rb +13 -1
- data/features/step_definitions/vcr_steps.rb +26 -16
- data/features/support/env.rb +13 -5
- data/features/webmock.feature +4 -4
- data/lib/vcr.rb +5 -5
- data/lib/vcr/cassette.rb +55 -19
- data/lib/vcr/extensions/net_http.rb +2 -4
- data/lib/vcr/http_stubbing_adapters/fakeweb.rb +0 -4
- data/lib/vcr/http_stubbing_adapters/webmock.rb +2 -9
- data/lib/vcr/internet_connection.rb +13 -0
- data/lib/vcr/ping.rb +26 -0
- data/lib/vcr/rspec.rb +39 -0
- data/lib/vcr/version.rb +1 -1
- data/spec/cassette_spec.rb +160 -69
- data/spec/config_spec.rb +1 -1
- data/spec/cucumber_tags_spec.rb +3 -2
- data/spec/deprecations_spec.rb +1 -1
- data/spec/extensions/net_http_response_spec.rb +2 -4
- data/spec/extensions/net_http_spec.rb +3 -1
- data/spec/fixtures/1.9.1/cassette_spec/with_localhost_requests.yml +23 -0
- data/spec/fixtures/not_1.9.1/cassette_spec/with_localhost_requests.yml +23 -0
- data/spec/http_stubbing_adapters/fakeweb_spec.rb +3 -9
- data/spec/http_stubbing_adapters/webmock_spec.rb +7 -18
- data/spec/internet_connection_spec.rb +19 -0
- data/spec/monkey_patches.rb +45 -6
- data/spec/request_matcher_spec.rb +1 -1
- data/spec/rspec_spec.rb +46 -0
- data/spec/spec_helper.rb +6 -11
- data/spec/structs_spec.rb +1 -1
- data/spec/support/fixnum_extension.rb +10 -0
- data/spec/support/http_library_adapters.rb +31 -2
- data/spec/support/ruby_interpreter.rb +7 -0
- data/spec/support/vcr_localhost_server.rb +86 -44
- data/spec/support/webmock_macros.rb +14 -0
- data/spec/vcr_spec.rb +1 -1
- data/spec/version_spec.rb +1 -1
- data/vcr.gemspec +10 -6
- metadata +155 -39
data/lib/vcr/ping.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# Ruby 1.8 provides Ping.pingecho, but it was removed in 1.9.
|
2
|
+
# So we try requiring it, and if that fails, define it ourselves.
|
3
|
+
begin
|
4
|
+
require 'ping'
|
5
|
+
rescue LoadError
|
6
|
+
# This is copied, verbatim, from Ruby 1.8.7's ping.rb.
|
7
|
+
require 'timeout'
|
8
|
+
require "socket"
|
9
|
+
|
10
|
+
module Ping
|
11
|
+
def pingecho(host, timeout=5, service="echo")
|
12
|
+
begin
|
13
|
+
timeout(timeout) do
|
14
|
+
s = TCPSocket.new(host, service)
|
15
|
+
s.close
|
16
|
+
end
|
17
|
+
rescue Errno::ECONNREFUSED
|
18
|
+
return true
|
19
|
+
rescue Timeout::Error, StandardError
|
20
|
+
return false
|
21
|
+
end
|
22
|
+
return true
|
23
|
+
end
|
24
|
+
module_function :pingecho
|
25
|
+
end
|
26
|
+
end
|
data/lib/vcr/rspec.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'vcr'
|
2
|
+
|
3
|
+
module VCR
|
4
|
+
module RSpec
|
5
|
+
module Macros
|
6
|
+
def use_vcr_cassette(*args)
|
7
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
8
|
+
name = args.first || infer_cassette_name
|
9
|
+
|
10
|
+
before(:each) do
|
11
|
+
VCR.insert_cassette(name, options)
|
12
|
+
end
|
13
|
+
|
14
|
+
after(:each) do
|
15
|
+
VCR.eject_cassette
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def infer_cassette_name
|
22
|
+
# RSpec 1 exposes #description_parts; use that if its available
|
23
|
+
return description_parts.join("/") if respond_to?(:description_parts)
|
24
|
+
|
25
|
+
# Otherwise use RSpec 2 metadata...
|
26
|
+
group_descriptions = []
|
27
|
+
klass = self
|
28
|
+
|
29
|
+
while klass.respond_to?(:metadata) && klass.metadata
|
30
|
+
group_descriptions << klass.metadata[:example_group][:description]
|
31
|
+
klass = klass.superclass
|
32
|
+
end
|
33
|
+
|
34
|
+
group_descriptions.compact.reverse.join('/')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
data/lib/vcr/version.rb
CHANGED
data/spec/cassette_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe VCR::Cassette do
|
4
4
|
describe '#file' do
|
@@ -27,11 +27,11 @@ describe VCR::Cassette do
|
|
27
27
|
end
|
28
28
|
|
29
29
|
describe '#record_http_interaction' do
|
30
|
-
it 'adds the interaction to #
|
30
|
+
it 'adds the interaction to #new_recorded_interactions' do
|
31
31
|
cassette = VCR::Cassette.new(:test_cassette)
|
32
|
-
cassette.
|
32
|
+
cassette.new_recorded_interactions.should == []
|
33
33
|
cassette.record_http_interaction(:the_interaction)
|
34
|
-
cassette.
|
34
|
+
cassette.new_recorded_interactions.should == [:the_interaction]
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
@@ -127,7 +127,7 @@ describe VCR::Cassette do
|
|
127
127
|
|
128
128
|
VCR::Cassette::VALID_RECORD_MODES.each do |record_mode|
|
129
129
|
http_connections_allowed = (record_mode != :none)
|
130
|
-
|
130
|
+
stub_requests = (record_mode != :all)
|
131
131
|
|
132
132
|
context "when VCR::Config.default_cassette_options[:record] is :#{record_mode}" do
|
133
133
|
before(:each) { VCR::Config.default_cassette_options = { :record => record_mode } }
|
@@ -138,47 +138,90 @@ describe VCR::Cassette do
|
|
138
138
|
end
|
139
139
|
end
|
140
140
|
|
141
|
-
context "when the record
|
141
|
+
context "when :#{record_mode} is passed as the record option" do
|
142
|
+
unless record_mode == :all
|
143
|
+
context "and re_record_interval is 7.days" do
|
144
|
+
let(:file_name) { File.join(VCR::Config.cassette_library_dir, "cassette_name.yml") }
|
145
|
+
subject { VCR::Cassette.new(File.basename(file_name).gsub('.yml', ''), :record => record_mode, :re_record_interval => 7.days) }
|
146
|
+
|
147
|
+
context 'when the cassette file does not exist' do
|
148
|
+
before(:each) { File.stub(:exist?).with(file_name).and_return(false) }
|
149
|
+
|
150
|
+
it "has :#{record_mode} for the record mode" do
|
151
|
+
subject.record_mode.should == record_mode
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
context 'when the cassette file does exist' do
|
156
|
+
before(:each) do
|
157
|
+
File.stub(:exist?).with(file_name).and_return(true)
|
158
|
+
File.stub(:read).with(file_name).and_return([].to_yaml)
|
159
|
+
end
|
160
|
+
|
161
|
+
context 'and the file was last modified less than 7 days ago' do
|
162
|
+
before(:each) { File.stub(:stat).with(file_name).and_return(stub(:mtime => Time.now - 7.days + 60)) }
|
163
|
+
|
164
|
+
it "has :#{record_mode} for the record mode" do
|
165
|
+
subject.record_mode.should == record_mode
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context 'and the file was last modified more than 7 days ago' do
|
170
|
+
before(:each) { File.stub(:stat).with(file_name).and_return(stub(:mtime => Time.now - 7.days - 60)) }
|
171
|
+
|
172
|
+
it "has :all for the record mode when there is an internet connection available" do
|
173
|
+
VCR::InternetConnection.stub(:available? => true)
|
174
|
+
subject.record_mode.should == :all
|
175
|
+
end
|
176
|
+
|
177
|
+
it "has :#{record_mode} for the record mode when there is no internet connection available" do
|
178
|
+
VCR::InternetConnection.stub(:available? => false)
|
179
|
+
subject.record_mode.should == record_mode
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
142
186
|
it "sets http_connections_allowed to #{http_connections_allowed} on the http stubbing adapter" do
|
143
187
|
VCR.http_stubbing_adapter.should_receive(:http_connections_allowed=).with(http_connections_allowed)
|
144
188
|
VCR::Cassette.new(:name, :record => record_mode)
|
145
189
|
end
|
146
190
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
expected_uri_hosts = %w(example.com)
|
151
|
-
expected_uri_hosts += VCR::LOCALHOST_ALIASES unless ignore_localhost
|
191
|
+
[true, false].each do |ignore_localhost|
|
192
|
+
expected_uri_hosts = %w(example.com)
|
193
|
+
expected_uri_hosts += VCR::LOCALHOST_ALIASES unless ignore_localhost
|
152
194
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
end
|
195
|
+
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
|
196
|
+
VCR.http_stubbing_adapter.stub!(:ignore_localhost?).and_return(ignore_localhost)
|
197
|
+
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
|
198
|
+
cassette = VCR::Cassette.new('with_localhost_requests', :record => record_mode)
|
199
|
+
cassette.recorded_interactions.map { |i| URI.parse(i.uri).host }.should =~ expected_uri_hosts
|
159
200
|
end
|
201
|
+
end
|
160
202
|
|
161
|
-
|
162
|
-
|
163
|
-
|
203
|
+
it "loads the recorded interactions from the library yml file" do
|
204
|
+
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
|
205
|
+
cassette = VCR::Cassette.new('example', :record => record_mode)
|
164
206
|
|
165
|
-
|
207
|
+
cassette.should have(3).recorded_interactions
|
166
208
|
|
167
|
-
|
209
|
+
i1, i2, i3 = *cassette.recorded_interactions
|
168
210
|
|
169
|
-
|
170
|
-
|
171
|
-
|
211
|
+
i1.request.method.should == :get
|
212
|
+
i1.request.uri.should == 'http://example.com:80/'
|
213
|
+
i1.response.body.should =~ /You have reached this web page by typing.+example\.com/
|
172
214
|
|
173
|
-
|
174
|
-
|
175
|
-
|
215
|
+
i2.request.method.should == :get
|
216
|
+
i2.request.uri.should == 'http://example.com:80/foo'
|
217
|
+
i2.response.body.should =~ /foo was not found on this server/
|
176
218
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
219
|
+
i3.request.method.should == :get
|
220
|
+
i3.request.uri.should == 'http://example.com:80/'
|
221
|
+
i3.response.body.should =~ /Another example\.com response/
|
222
|
+
end
|
181
223
|
|
224
|
+
if stub_requests
|
182
225
|
it "stubs the recorded requests with the http stubbing adapter" do
|
183
226
|
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
|
184
227
|
VCR.http_stubbing_adapter.should_receive(:stub_requests).with([an_instance_of(VCR::HTTPInteraction)]*3, anything)
|
@@ -190,21 +233,12 @@ describe VCR::Cassette do
|
|
190
233
|
VCR.http_stubbing_adapter.should_receive(:stub_requests).with(anything, [:body, :headers])
|
191
234
|
cassette = VCR::Cassette.new('example', :record => record_mode, :match_requests_on => [:body, :headers])
|
192
235
|
end
|
193
|
-
|
194
236
|
else
|
195
|
-
|
196
237
|
it "does not stub the recorded requests with the http stubbing adapter" do
|
197
238
|
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
|
198
239
|
VCR.http_stubbing_adapter.should_not_receive(:stub_requests)
|
199
240
|
cassette = VCR::Cassette.new('example', :record => record_mode)
|
200
241
|
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
242
|
end
|
209
243
|
end
|
210
244
|
end
|
@@ -230,7 +264,7 @@ describe VCR::Cassette do
|
|
230
264
|
]
|
231
265
|
|
232
266
|
cassette = VCR::Cassette.new(:eject_test)
|
233
|
-
cassette.stub!(:
|
267
|
+
cassette.stub!(:new_recorded_interactions).and_return(recorded_interactions)
|
234
268
|
|
235
269
|
lambda { cassette.eject }.should change { File.exist?(cassette.file) }.from(false).to(true)
|
236
270
|
saved_recorded_interactions = File.open(cassette.file, "r") { |f| YAML.load(f.read) }
|
@@ -240,41 +274,98 @@ describe VCR::Cassette do
|
|
240
274
|
it "writes the recorded interactions to a subdirectory if the cassette name includes a directory" do
|
241
275
|
recorded_interactions = [VCR::HTTPInteraction.new(:the_request, :the_response)]
|
242
276
|
cassette = VCR::Cassette.new('subdirectory/test_cassette')
|
243
|
-
cassette.stub!(:
|
277
|
+
cassette.stub!(:new_recorded_interactions).and_return(recorded_interactions)
|
244
278
|
|
245
279
|
lambda { cassette.eject }.should change { File.exist?(cassette.file) }.from(false).to(true)
|
246
280
|
saved_recorded_interactions = File.open(cassette.file, "r") { |f| YAML.load(f.read) }
|
247
281
|
saved_recorded_interactions.should == recorded_interactions
|
248
282
|
end
|
249
283
|
|
250
|
-
|
251
|
-
|
252
|
-
|
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
|
284
|
+
[:all, :none, :new_episodes].each do |record_mode|
|
285
|
+
context "for a :record => :#{record_mode} cassette with previously recorded interactions" do
|
286
|
+
temp_dir File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec/temp"), :assign_to_cassette_library_dir => true
|
263
287
|
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
288
|
+
subject { VCR::Cassette.new('example', :record => record_mode, :match_requests_on => [:uri]) }
|
289
|
+
|
290
|
+
before(:each) do
|
291
|
+
base_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
|
292
|
+
FileUtils.cp(base_dir + "/example.yml", base_dir + "/temp/example.yml")
|
293
|
+
end
|
294
|
+
|
295
|
+
it "restore the stubs checkpoint on the http stubbing adapter" do
|
296
|
+
VCR.http_stubbing_adapter.should_receive(:restore_stubs_checkpoint).with('example')
|
297
|
+
subject.eject
|
298
|
+
end
|
299
|
+
|
300
|
+
it "does not re-write to disk the previously recorded interactions if there are no new ones" do
|
301
|
+
yaml_file = subject.file
|
302
|
+
File.should_not_receive(:open).with(subject.file, 'w')
|
303
|
+
lambda { subject.eject }.should_not change { File.mtime(yaml_file) }
|
304
|
+
end
|
305
|
+
|
306
|
+
context 'when some new interactions have been recorded' do
|
307
|
+
let(:new_interaction_1) { VCR::HTTPInteraction.new(VCR::Request.new, :response_1) }
|
308
|
+
let(:new_interaction_2) { VCR::HTTPInteraction.new(VCR::Request.new, :response_2) }
|
309
|
+
let(:new_interaction_3) { VCR::HTTPInteraction.new(VCR::Request.new, :response_3) }
|
310
|
+
|
311
|
+
let(:old_interaction_1) { subject.recorded_interactions[0] }
|
312
|
+
let(:old_interaction_2) { subject.recorded_interactions[1] }
|
313
|
+
let(:old_interaction_3) { subject.recorded_interactions[2] }
|
314
|
+
|
315
|
+
let(:saved_recorded_interactions) { YAML.load(File.read(subject.file)) }
|
316
|
+
|
317
|
+
before(:each) do
|
318
|
+
old_interaction_1.request.stub(:matcher => :matcher_c)
|
319
|
+
old_interaction_2.request.stub(:matcher => :matcher_d)
|
320
|
+
old_interaction_3.request.stub(:matcher => :matcher_c)
|
321
|
+
|
322
|
+
new_interaction_1.request.stub(:matcher => :matcher_a)
|
323
|
+
new_interaction_2.request.stub(:matcher => :matcher_b)
|
324
|
+
new_interaction_3.request.stub(:matcher => :matcher_c)
|
271
325
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
326
|
+
[new_interaction_1, new_interaction_2, new_interaction_3].each do |i|
|
327
|
+
subject.record_http_interaction(i)
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
if record_mode == :all
|
332
|
+
it 'removes the old interactions that match new requests, and saves the new interactions follow the old ones' do
|
333
|
+
subject.eject
|
334
|
+
|
335
|
+
saved_recorded_interactions.should == [
|
336
|
+
old_interaction_2,
|
337
|
+
new_interaction_1,
|
338
|
+
new_interaction_2,
|
339
|
+
new_interaction_3
|
340
|
+
]
|
341
|
+
end
|
342
|
+
|
343
|
+
it "matches old requests to new ones using the cassette's match attributes" do
|
344
|
+
[
|
345
|
+
old_interaction_1, old_interaction_2, old_interaction_3,
|
346
|
+
new_interaction_1, new_interaction_2, new_interaction_3
|
347
|
+
].each do |i|
|
348
|
+
i.request.should_receive(:matcher).with(subject.match_requests_on).and_return(:the_matcher)
|
349
|
+
end
|
350
|
+
|
351
|
+
subject.eject
|
352
|
+
end
|
353
|
+
else
|
354
|
+
it 'saves the old interactions followed by the new ones to disk' do
|
355
|
+
subject.eject
|
356
|
+
|
357
|
+
saved_recorded_interactions.should == [
|
358
|
+
old_interaction_1,
|
359
|
+
old_interaction_2,
|
360
|
+
old_interaction_3,
|
361
|
+
new_interaction_1,
|
362
|
+
new_interaction_2,
|
363
|
+
new_interaction_3
|
364
|
+
]
|
365
|
+
end
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|
278
369
|
end
|
279
370
|
end
|
280
371
|
end
|
data/spec/config_spec.rb
CHANGED
data/spec/cucumber_tags_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe VCR::CucumberTags do
|
4
4
|
subject { described_class.new(self) }
|
@@ -12,7 +12,8 @@ describe VCR::CucumberTags do
|
|
12
12
|
def test_tag(cassette_attribute, tag, expected_value)
|
13
13
|
VCR.current_cassette.should be_nil
|
14
14
|
|
15
|
-
cassette_during_scenario
|
15
|
+
cassette_during_scenario = nil
|
16
|
+
scenario = lambda { cassette_during_scenario = VCR.current_cassette }
|
16
17
|
blocks_for_tags[tag].call(:scenario_name, scenario)
|
17
18
|
cassette_during_scenario.send(cassette_attribute).should == expected_value
|
18
19
|
|
data/spec/deprecations_spec.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe VCR::Net::HTTPResponse do
|
4
|
-
|
5
|
-
before(:all) { MonkeyPatches.disable! }
|
6
|
-
after(:all) { MonkeyPatches.enable! }
|
4
|
+
without_monkey_patches :all
|
7
5
|
|
8
6
|
def self.it_allows_the_body_to_be_read(expected_regex)
|
9
7
|
it 'allows the body to be read using #body' do
|
@@ -1,6 +1,8 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe "Net::HTTP Extensions" do
|
4
|
+
without_webmock_callbacks
|
5
|
+
|
4
6
|
let(:uri) { URI.parse('http://example.com') }
|
5
7
|
|
6
8
|
it 'checks if the request is stubbed using a VCR::Request' do
|
@@ -53,6 +53,29 @@
|
|
53
53
|
- "277"
|
54
54
|
:body: 127.0.0.1 response
|
55
55
|
:http_version: "1.1"
|
56
|
+
- !ruby/struct:VCR::HTTPInteraction
|
57
|
+
:request: !ruby/struct:VCR::Request
|
58
|
+
:method: :get
|
59
|
+
:uri: http://0.0.0.0:80/
|
60
|
+
:body:
|
61
|
+
:headers:
|
62
|
+
:response: !ruby/struct:VCR::Response
|
63
|
+
:status: !ruby/struct:VCR::ResponseStatus
|
64
|
+
:code: 404
|
65
|
+
:message: Not Found
|
66
|
+
:headers:
|
67
|
+
content-type:
|
68
|
+
- text/html; charset=iso-8859-1
|
69
|
+
connection:
|
70
|
+
- close
|
71
|
+
server:
|
72
|
+
- Apache/2.2.3 (CentOS)
|
73
|
+
date:
|
74
|
+
- Thu, 25 Feb 2010 07:53:52 GMT
|
75
|
+
content-length:
|
76
|
+
- "277"
|
77
|
+
:body: 127.0.0.1 response
|
78
|
+
:http_version: "1.1"
|
56
79
|
- !ruby/struct:VCR::HTTPInteraction
|
57
80
|
:request: !ruby/struct:VCR::Request
|
58
81
|
:method: :get
|