vcr 2.0.0.beta2 → 2.0.0.rc1
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 -0
- data/.travis.yml +0 -2
- data/CHANGELOG.md +22 -1
- data/CONTRIBUTING.md +46 -0
- data/Gemfile +1 -9
- data/README.md +8 -2
- data/Rakefile +12 -1
- data/cucumber.yml +8 -9
- data/features/.nav +10 -4
- data/features/cassettes/format.feature +1 -1
- data/features/cassettes/no_cassette.feature +8 -11
- data/features/configuration/allow_http_connections_when_no_cassette.feature +4 -4
- data/features/configuration/filter_sensitive_data.feature +3 -0
- data/features/configuration/hook_into.feature +4 -8
- data/features/configuration/ignore_request.feature +191 -0
- data/features/getting_started.md +38 -21
- data/features/hooks/after_http_request.feature +44 -0
- data/features/hooks/around_http_request.feature +56 -0
- data/features/hooks/before_http_request.feature +44 -0
- data/features/hooks/before_playback.feature +181 -0
- data/features/hooks/before_record.feature +172 -0
- data/features/middleware/faraday.feature +7 -3
- data/features/record_modes/none.feature +2 -1
- data/features/record_modes/once.feature +2 -1
- data/features/request_matching/body.feature +2 -2
- data/features/request_matching/custom_matcher.feature +2 -2
- data/features/request_matching/headers.feature +2 -2
- data/features/request_matching/host.feature +2 -2
- data/features/request_matching/identical_request_sequence.feature +2 -2
- data/features/request_matching/method.feature +2 -2
- data/features/request_matching/path.feature +2 -2
- data/features/request_matching/playback_repeats.feature +2 -1
- data/features/request_matching/uri.feature +2 -2
- data/features/support/env.rb +21 -12
- data/features/test_frameworks/cucumber.feature +9 -4
- data/features/test_frameworks/{rspec.feature → rspec_macro.feature} +7 -7
- data/features/test_frameworks/rspec_metadata.feature +90 -0
- data/lib/vcr.rb +1 -1
- data/lib/vcr/cassette.rb +3 -3
- data/lib/vcr/cassette/http_interaction_list.rb +13 -9
- data/lib/vcr/cassette/migrator.rb +1 -1
- data/lib/vcr/configuration.rb +37 -0
- data/lib/vcr/errors.rb +172 -6
- data/lib/vcr/library_hooks.rb +4 -6
- data/lib/vcr/library_hooks/excon.rb +23 -11
- data/lib/vcr/library_hooks/fakeweb.rb +85 -24
- data/lib/vcr/library_hooks/faraday.rb +30 -2
- data/lib/vcr/library_hooks/typhoeus.rb +25 -3
- data/lib/vcr/library_hooks/webmock.rb +25 -36
- data/lib/vcr/middleware/faraday.rb +23 -5
- data/lib/vcr/request_handler.rb +12 -1
- data/lib/vcr/request_ignorer.rb +12 -1
- data/lib/vcr/request_matcher_registry.rb +1 -9
- data/lib/vcr/structs.rb +32 -2
- data/lib/vcr/test_frameworks/rspec.rb +28 -0
- data/lib/vcr/util/hooks.rb +12 -4
- data/lib/vcr/util/version_checker.rb +2 -0
- data/lib/vcr/version.rb +1 -1
- data/spec/fixtures/cassette_spec/example.yml +1 -1
- data/spec/fixtures/{fake_example.com_responses.yml → fake_example_responses.yml} +0 -0
- data/spec/monkey_patches.rb +1 -1
- data/spec/spec_helper.rb +3 -1
- data/spec/support/http_library_adapters.rb +4 -3
- data/spec/support/shared_example_groups/hook_into_http_library.rb +194 -12
- data/spec/support/shared_example_groups/request_hooks.rb +58 -0
- data/spec/support/shared_example_groups/version_checking.rb +5 -0
- data/spec/support/sinatra_app.rb +17 -9
- data/spec/support/vcr_stub_helpers.rb +17 -0
- data/spec/vcr/cassette/http_interaction_list_spec.rb +28 -29
- data/spec/vcr/cassette/migrator_spec.rb +6 -7
- data/spec/vcr/cassette_spec.rb +5 -5
- data/spec/vcr/configuration_spec.rb +51 -32
- data/spec/vcr/deprecations_spec.rb +0 -8
- data/spec/vcr/errors_spec.rb +129 -0
- data/spec/vcr/library_hooks/excon_spec.rb +21 -4
- data/spec/vcr/library_hooks/fakeweb_spec.rb +71 -3
- data/spec/vcr/library_hooks/faraday_spec.rb +45 -0
- data/spec/vcr/library_hooks/typhoeus_spec.rb +31 -1
- data/spec/vcr/library_hooks/webmock_spec.rb +26 -3
- data/spec/vcr/middleware/faraday_spec.rb +84 -1
- data/spec/vcr/request_ignorer_spec.rb +16 -0
- data/spec/vcr/request_matcher_registry_spec.rb +0 -26
- data/spec/vcr/structs_spec.rb +61 -1
- data/spec/vcr/test_frameworks/rspec_spec.rb +32 -0
- data/spec/vcr/util/hooks_spec.rb +73 -63
- data/spec/vcr_spec.rb +2 -2
- data/vcr.gemspec +5 -5
- metadata +51 -31
- data/features/configuration/hooks.feature +0 -270
- data/features/configuration/ignore_hosts.feature +0 -61
- data/features/configuration/ignore_localhost.feature +0 -97
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'vcr/library_hooks/faraday'
|
3
|
+
|
4
|
+
describe "Faraday hook" do
|
5
|
+
it 'inserts the VCR middleware just before the adapter' do
|
6
|
+
conn = Faraday.new(:url => 'http://sushi.com') do |builder|
|
7
|
+
builder.request :url_encoded
|
8
|
+
builder.request :json
|
9
|
+
builder.response :logger
|
10
|
+
builder.adapter :net_http
|
11
|
+
end
|
12
|
+
|
13
|
+
conn.builder.lock!
|
14
|
+
conn.builder.handlers.last(2).map(&:klass).should eq([
|
15
|
+
VCR::Middleware::Faraday,
|
16
|
+
Faraday::Adapter::NetHttp
|
17
|
+
])
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'handles the case where no adapter is declared' do
|
21
|
+
conn = Faraday.new
|
22
|
+
|
23
|
+
conn.builder.lock!
|
24
|
+
conn.builder.handlers.last(2).map(&:klass).should eq([
|
25
|
+
VCR::Middleware::Faraday,
|
26
|
+
Faraday::Adapter::NetHttp
|
27
|
+
])
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'does nothing if the VCR middleware has already been included' do
|
31
|
+
conn = Faraday.new(:url => 'http://sushi.com') do |builder|
|
32
|
+
builder.use VCR::Middleware::Faraday
|
33
|
+
builder.use Faraday::Response::Logger
|
34
|
+
builder.use Faraday::Adapter::NetHttp
|
35
|
+
end
|
36
|
+
|
37
|
+
conn.builder.lock!
|
38
|
+
conn.builder.handlers.map(&:klass).should eq([
|
39
|
+
VCR::Middleware::Faraday,
|
40
|
+
Faraday::Response::Logger,
|
41
|
+
Faraday::Adapter::NetHttp
|
42
|
+
])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -1,7 +1,35 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe "Typhoeus hook", :with_monkey_patches => :typhoeus do
|
4
|
-
|
4
|
+
after(:each) do
|
5
|
+
::Typhoeus::Hydra.clear_stubs
|
6
|
+
end
|
7
|
+
|
8
|
+
def disable_real_connections
|
9
|
+
::Typhoeus::Hydra.allow_net_connect = false
|
10
|
+
::Typhoeus::Hydra::NetConnectNotAllowedError
|
11
|
+
end
|
12
|
+
|
13
|
+
def enable_real_connections
|
14
|
+
::Typhoeus::Hydra.allow_net_connect = true
|
15
|
+
end
|
16
|
+
|
17
|
+
def directly_stub_request(method, url, response_body)
|
18
|
+
response = ::Typhoeus::Response.new(:code => 200, :body => response_body)
|
19
|
+
::Typhoeus::Hydra.stub(method, url).and_return(response)
|
20
|
+
end
|
21
|
+
|
22
|
+
it_behaves_like 'a hook into an HTTP library', :typhoeus, 'typhoeus'
|
23
|
+
|
24
|
+
def stub_callback_registration
|
25
|
+
# stub the callback registration methods so we don't get a second
|
26
|
+
# callback registered when we load the typhoeus file below.
|
27
|
+
# Note that we have to use `stub!`, not `stub` because
|
28
|
+
# Typhoeus::Hydra defines its own stub method...so to use RSpec's,
|
29
|
+
# we use stub!
|
30
|
+
::Typhoeus::Hydra.stub!(:after_request_before_on_complete)
|
31
|
+
::Typhoeus::Hydra.stub!(:register_stub_finder)
|
32
|
+
end
|
5
33
|
|
6
34
|
it_performs('version checking', 'Typhoeus',
|
7
35
|
:valid => %w[ 0.3.2 0.3.10 ],
|
@@ -18,6 +46,8 @@ describe "Typhoeus hook", :with_monkey_patches => :typhoeus do
|
|
18
46
|
end
|
19
47
|
|
20
48
|
describe "VCR.configuration.after_library_hooks_loaded hook", :disable_warnings do
|
49
|
+
before(:each) { stub_callback_registration }
|
50
|
+
|
21
51
|
it 'disables the webmock typhoeus adapter so it does not conflict with our typhoeus hook' do
|
22
52
|
load "vcr/library_hooks/typhoeus.rb" # to re-add the hook since it's cleared by each test
|
23
53
|
::WebMock::HttpLibAdapters::TyphoeusAdapter.should_receive(:disable!)
|
@@ -1,8 +1,25 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe "WebMock hook", :with_monkey_patches => :webmock do
|
4
|
+
after(:each) do
|
5
|
+
::WebMock.reset!
|
6
|
+
end
|
7
|
+
|
8
|
+
def disable_real_connections
|
9
|
+
::WebMock.disable_net_connect!
|
10
|
+
::WebMock::NetConnectNotAllowedError
|
11
|
+
end
|
12
|
+
|
13
|
+
def enable_real_connections
|
14
|
+
::WebMock.allow_net_connect!
|
15
|
+
end
|
16
|
+
|
17
|
+
def directly_stub_request(method, url, response_body)
|
18
|
+
::WebMock.stub_request(method, url).to_return(:body => response_body)
|
19
|
+
end
|
20
|
+
|
4
21
|
%w[net/http patron httpclient em-http-request curb typhoeus].each do |lib|
|
5
|
-
it_behaves_like 'a hook into an HTTP library', lib do
|
22
|
+
it_behaves_like 'a hook into an HTTP library', :webmock, lib do
|
6
23
|
if lib == 'net/http'
|
7
24
|
def normalize_request_headers(headers)
|
8
25
|
headers.merge(DEFAULT_REQUEST_HEADERS)
|
@@ -12,10 +29,16 @@ describe "WebMock hook", :with_monkey_patches => :webmock do
|
|
12
29
|
end
|
13
30
|
|
14
31
|
it_performs('version checking', 'WebMock',
|
15
|
-
:valid => %w[ 1.7.
|
16
|
-
:too_low => %w[ 0.9.9 0.9.10 0.1.30 1.0.30 1.
|
32
|
+
:valid => %w[ 1.7.8 1.7.10 1.7.99 ],
|
33
|
+
:too_low => %w[ 0.9.9 0.9.10 0.1.30 1.0.30 1.7.7 ],
|
17
34
|
:too_high => %w[ 1.8.0 1.10.0 2.0.0 ]
|
18
35
|
) do
|
36
|
+
|
37
|
+
def stub_callback_registration
|
38
|
+
::WebMock.stub(:after_request)
|
39
|
+
::WebMock.stub(:globally_stub_request)
|
40
|
+
end
|
41
|
+
|
19
42
|
def stub_version(version)
|
20
43
|
WebMock.stub(:version).and_return(version)
|
21
44
|
end
|
@@ -1,8 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'vcr/library_hooks/faraday'
|
2
3
|
|
3
4
|
describe VCR::Middleware::Faraday do
|
4
5
|
%w[ typhoeus net_http patron ].each do |lib|
|
5
|
-
it_behaves_like 'a hook into an HTTP library', "faraday (w/ #{lib})",
|
6
|
+
it_behaves_like 'a hook into an HTTP library', :faraday, "faraday (w/ #{lib})",
|
6
7
|
:status_message_not_exposed,
|
7
8
|
:does_not_support_rotating_responses,
|
8
9
|
:not_disableable
|
@@ -22,4 +23,86 @@ describe VCR::Middleware::Faraday do
|
|
22
23
|
::Faraday::VERSION = version
|
23
24
|
end
|
24
25
|
end
|
26
|
+
|
27
|
+
context 'when making parallel requests' do
|
28
|
+
include VCRStubHelpers
|
29
|
+
let(:parallel_manager) { ::Faraday::Adapter::Typhoeus.setup_parallel_manager }
|
30
|
+
let(:connection) { ::Faraday.new { |b| b.adapter :typhoeus } }
|
31
|
+
|
32
|
+
shared_examples_for "exclusive library hook" do
|
33
|
+
let(:request_url) { "http://localhost:#{VCR::SinatraApp.port}/" }
|
34
|
+
|
35
|
+
def make_request
|
36
|
+
connection.in_parallel(parallel_manager) { connection.get(request_url) }
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'makes the faraday middleware exclusively enabled for the duration of the request' do
|
40
|
+
VCR.library_hooks.should_not be_disabled(:fakeweb)
|
41
|
+
|
42
|
+
hook_called = false
|
43
|
+
VCR.configuration.after_http_request do
|
44
|
+
hook_called = true
|
45
|
+
VCR.library_hooks.should be_disabled(:fakeweb)
|
46
|
+
end
|
47
|
+
|
48
|
+
make_request
|
49
|
+
VCR.library_hooks.should_not be_disabled(:fakeweb)
|
50
|
+
hook_called.should be_true
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'for an ignored request' do
|
55
|
+
before(:each) { VCR.configuration.ignore_request { true } }
|
56
|
+
it_behaves_like "exclusive library hook"
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'for a stubbed request' do
|
60
|
+
it_behaves_like "exclusive library hook" do
|
61
|
+
before(:each) do
|
62
|
+
stub_requests([http_interaction(request_url)], [:method, :uri])
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'for a recorded request' do
|
68
|
+
let!(:inserted_cassette) { VCR.insert_cassette('new_cassette') }
|
69
|
+
before(:each) { VCR.should_receive(:record_http_interaction) }
|
70
|
+
it_behaves_like "exclusive library hook"
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'for a disallowed request' do
|
74
|
+
it_behaves_like "exclusive library hook" do
|
75
|
+
undef make_request
|
76
|
+
def make_request
|
77
|
+
expect {
|
78
|
+
connection.in_parallel(parallel_manager) { connection.get(request_url) }
|
79
|
+
}.to raise_error(VCR::Errors::UnhandledHTTPRequestError)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
it_behaves_like "request hooks", :faraday do
|
85
|
+
let!(:inserted_cassette) { VCR.insert_cassette('new_cassette') }
|
86
|
+
|
87
|
+
undef make_request
|
88
|
+
def make_request(disabled = false)
|
89
|
+
response = nil
|
90
|
+
connection.in_parallel(parallel_manager) do
|
91
|
+
response = connection.get(request_url)
|
92
|
+
end
|
93
|
+
response
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'can be used to eject a cassette after the request is recorded' do
|
97
|
+
VCR.configuration.after_http_request { |request| VCR.eject_cassette }
|
98
|
+
|
99
|
+
VCR.should_receive(:record_http_interaction) do |interaction|
|
100
|
+
VCR.current_cassette.should be(inserted_cassette)
|
101
|
+
end
|
102
|
+
|
103
|
+
make_request
|
104
|
+
VCR.current_cassette.should be_nil
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end if defined?(::Typhoeus)
|
25
108
|
end
|
@@ -49,6 +49,22 @@ module VCR
|
|
49
49
|
it_behaves_like "#ignore?", "http://#{host}/foo", false
|
50
50
|
end
|
51
51
|
end
|
52
|
+
|
53
|
+
context 'when a custom ignore_request hook has been set' do
|
54
|
+
before(:each) do
|
55
|
+
subject.ignore_request do |request|
|
56
|
+
URI(request.uri).port == 5
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'ignores requests for which the block returns true' do
|
61
|
+
subject.ignore?(request('http://foo.com:5/bar')).should be_true
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'does not ignore requests for which the block returns false' do
|
65
|
+
subject.ignore?(request('http://foo.com:6/bar')).should be_false
|
66
|
+
end
|
67
|
+
end
|
52
68
|
end
|
53
69
|
end
|
54
70
|
|
@@ -168,32 +168,6 @@ module VCR
|
|
168
168
|
request_with(:uri => 'http://foo2.com/bar?baz=7')
|
169
169
|
).should be_false
|
170
170
|
end
|
171
|
-
|
172
|
-
it 'does not consider the standard HTTP port' do
|
173
|
-
subject[:uri].matches?(
|
174
|
-
request_with(:uri => 'http://foo.com:80/bar?baz=7'),
|
175
|
-
request_with(:uri => 'http://foo.com/bar?baz=7')
|
176
|
-
).should be_true
|
177
|
-
end
|
178
|
-
|
179
|
-
it 'does not consider the standard HTTPS port' do
|
180
|
-
subject[:uri].matches?(
|
181
|
-
request_with(:uri => 'https://foo.com/bar?baz=7'),
|
182
|
-
request_with(:uri => 'https://foo.com:443/bar?baz=7')
|
183
|
-
).should be_true
|
184
|
-
end
|
185
|
-
|
186
|
-
it 'considers non-standard ports' do
|
187
|
-
subject[:uri].matches?(
|
188
|
-
request_with(:uri => 'http://foo.com:79/bar?baz=7'),
|
189
|
-
request_with(:uri => 'http://foo.com:78/bar?baz=7')
|
190
|
-
).should be_false
|
191
|
-
|
192
|
-
subject[:uri].matches?(
|
193
|
-
request_with(:uri => 'https://foo.com:442/bar?baz=7'),
|
194
|
-
request_with(:uri => 'https://foo.com:441/bar?baz=7')
|
195
|
-
).should be_false
|
196
|
-
end
|
197
171
|
end
|
198
172
|
|
199
173
|
describe ":host" do
|
data/spec/vcr/structs_spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
1
3
|
require 'yaml'
|
2
4
|
require 'vcr/structs'
|
3
5
|
|
@@ -222,7 +224,7 @@ module VCR
|
|
222
224
|
end
|
223
225
|
|
224
226
|
it 'replaces sensitive text in the request URI' do
|
225
|
-
subject.request.uri.should eq('http://example-AAA.com
|
227
|
+
subject.request.uri.should eq('http://example-AAA.com/AAA/')
|
226
228
|
end
|
227
229
|
end
|
228
230
|
end
|
@@ -244,8 +246,59 @@ module VCR
|
|
244
246
|
m.call.should eq(described_class)
|
245
247
|
end
|
246
248
|
end
|
249
|
+
|
250
|
+
it 'gets normalized to a lowercase symbol' do
|
251
|
+
VCR::Request.new("GET").method.should eq(:get)
|
252
|
+
VCR::Request.new(:GET).method.should eq(:get)
|
253
|
+
VCR::Request.new(:get).method.should eq(:get)
|
254
|
+
VCR::Request.new("get").method.should eq(:get)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
describe "#uri" do
|
259
|
+
def uri_for(uri)
|
260
|
+
VCR::Request.new(:get, uri).uri
|
261
|
+
end
|
262
|
+
|
263
|
+
it 'removes the default http port' do
|
264
|
+
uri_for("http://foo.com:80/bar").should eq("http://foo.com/bar")
|
265
|
+
end
|
266
|
+
|
267
|
+
it 'removes the default https port' do
|
268
|
+
uri_for("https://foo.com:443/bar").should eq("https://foo.com/bar")
|
269
|
+
end
|
270
|
+
|
271
|
+
it 'does not remove a non-standard http port' do
|
272
|
+
uri_for("http://foo.com:81/bar").should eq("http://foo.com:81/bar")
|
273
|
+
end
|
274
|
+
|
275
|
+
it 'does not remove a non-standard https port' do
|
276
|
+
uri_for("https://foo.com:442/bar").should eq("https://foo.com:442/bar")
|
277
|
+
end
|
247
278
|
end
|
248
279
|
|
280
|
+
describe "#fiber_aware" do
|
281
|
+
it 'adds a #proceed method that yields in a fiber' do
|
282
|
+
fiber = Fiber.new do |request|
|
283
|
+
request.proceed
|
284
|
+
:done
|
285
|
+
end
|
286
|
+
|
287
|
+
fiber.resume(subject.fiber_aware).should be_nil
|
288
|
+
fiber.resume.should eq(:done)
|
289
|
+
end
|
290
|
+
|
291
|
+
it 'can be cast to a proc' do
|
292
|
+
request = subject.fiber_aware
|
293
|
+
request.should_receive(:proceed)
|
294
|
+
lambda(&request).call
|
295
|
+
end
|
296
|
+
|
297
|
+
it 'returns the request' do
|
298
|
+
subject.fiber_aware.should be(subject)
|
299
|
+
end
|
300
|
+
end if RUBY_VERSION > '1.9'
|
301
|
+
|
249
302
|
it_behaves_like 'a header normalizer' do
|
250
303
|
def with_headers(headers)
|
251
304
|
described_class.new(:get, 'http://example.com/', nil, headers)
|
@@ -301,6 +354,13 @@ module VCR
|
|
301
354
|
inst.update_content_length_header
|
302
355
|
}.to change { inst.headers[header] }.from(['3']).to(['0'])
|
303
356
|
end
|
357
|
+
|
358
|
+
it 'sets the header according to RFC 2616 based on the number of bytes (not the number of characters)' do
|
359
|
+
inst = instance('aؼ', '2') # the second char is a double byte char
|
360
|
+
expect {
|
361
|
+
inst.update_content_length_header
|
362
|
+
}.to change { inst.headers[header] }.from(['2']).to(['3'])
|
363
|
+
end
|
304
364
|
end
|
305
365
|
end
|
306
366
|
end
|
@@ -1,5 +1,37 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
+
RSpec.configure do |config|
|
4
|
+
config.before(:suite) do
|
5
|
+
VCR.configuration.configure_rspec_metadata!
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe VCR::RSpec::Metadata, :skip_vcr_reset do
|
10
|
+
before(:all) { VCR.reset! }
|
11
|
+
after(:each) { VCR.reset! }
|
12
|
+
|
13
|
+
context 'an example group', :vcr do
|
14
|
+
context 'with a nested example group' do
|
15
|
+
it 'uses a cassette for any examples' do
|
16
|
+
VCR.current_cassette.name.split('/').should eq([
|
17
|
+
'VCR::RSpec::Metadata',
|
18
|
+
'an example group',
|
19
|
+
'with a nested example group',
|
20
|
+
'uses a cassette for any examples'
|
21
|
+
])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'allows the cassette name to be overriden', :vcr => { :cassette_name => 'foo' } do
|
27
|
+
VCR.current_cassette.name.should eq('foo')
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'allows the cassette options to be set', :vcr => { :match_requests_on => [:method] } do
|
31
|
+
VCR.current_cassette.match_requests_on.should eq([:method])
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
3
35
|
describe VCR::RSpec::Macros do
|
4
36
|
extend described_class
|
5
37
|
|
data/spec/vcr/util/hooks_spec.rb
CHANGED
@@ -17,76 +17,86 @@ describe VCR::Hooks do
|
|
17
17
|
it 'clears all hooks' do
|
18
18
|
subject.before_foo { invocations << :callback }
|
19
19
|
subject.clear_hooks
|
20
|
-
subject.invoke_hook(:before_foo
|
20
|
+
subject.invoke_hook(:before_foo)
|
21
21
|
invocations.should be_empty
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
describe '#invoke_hook(:before_foo)' do
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
invocations.should be_empty
|
32
|
-
subject.invoke_hook(:before_foo, :green)
|
33
|
-
invocations.should eq([:callback_1, :callback_2])
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'invokes each of the :before_foo callbacks with no tag' do
|
37
|
-
subject.before_foo { invocations << :no_tag_1 }
|
38
|
-
subject.before_foo { invocations << :no_tag_2 }
|
39
|
-
|
40
|
-
subject.invoke_hook(:before_foo, :green)
|
41
|
-
invocations.should eq([:no_tag_1, :no_tag_2])
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'does not invoke any callbacks with a different tag' do
|
45
|
-
subject.before_foo(:blue) { invocations << :blue_callback }
|
46
|
-
subject.invoke_hook(:before_foo, :green)
|
47
|
-
invocations.should be_empty
|
48
|
-
end
|
26
|
+
it 'maps the return value of each callback' do
|
27
|
+
subject.before_foo { 17 }
|
28
|
+
subject.before_foo { 12 }
|
29
|
+
subject.invoke_hook(:before_foo).should eq([17, 12])
|
49
30
|
end
|
50
31
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
32
|
+
it 'invokes each of the :before_foo callbacks' do
|
33
|
+
subject.before_foo { invocations << :callback_1 }
|
34
|
+
subject.before_foo { invocations << :callback_2 }
|
35
|
+
|
36
|
+
invocations.should be_empty
|
37
|
+
subject.invoke_hook(:before_foo)
|
38
|
+
invocations.should eq([:callback_1, :callback_2])
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'does not invoke :before_bar callbacks' do
|
42
|
+
subject.before_bar { invocations << :bar_callback }
|
43
|
+
subject.invoke_hook(:before_foo)
|
44
|
+
invocations.should be_empty
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'does not invoke any tagged callbacks' do
|
48
|
+
subject.before_foo(:blue) { invocations << :blue_callback }
|
49
|
+
subject.invoke_hook(:before_foo)
|
50
|
+
invocations.should be_empty
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'passes along the provided arguments to the callback' do
|
54
|
+
subject.before_foo(&lambda { |a, b| invocations << [a, b] })
|
55
|
+
subject.invoke_hook(:before_foo, :arg1, :arg2)
|
56
|
+
invocations.flatten.should eq([:arg1, :arg2])
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'only passes along 1 argument when the block accepts only 1 arguments' do
|
60
|
+
subject.before_foo(&lambda { |a| invocations << a })
|
61
|
+
subject.invoke_hook(:before_foo, :arg1, :arg2)
|
62
|
+
invocations.flatten.should eq([:arg1])
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'passes along all arguments when the block accepts a variable number of args' do
|
66
|
+
subject.before_foo(&lambda { |*a| invocations << a })
|
67
|
+
subject.invoke_hook(:before_foo, :arg1, :arg2)
|
68
|
+
invocations.flatten.should eq([:arg1, :arg2])
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "#invoke_tagged_hook(:before_foo, tag)" do
|
73
|
+
it 'invokes each of the :before_foo callbacks with a matching tag' do
|
74
|
+
subject.before_foo(:green) { invocations << :callback_1 }
|
75
|
+
subject.before_foo(:green) { invocations << :callback_2 }
|
76
|
+
|
77
|
+
invocations.should be_empty
|
78
|
+
subject.invoke_tagged_hook(:before_foo, :green)
|
79
|
+
invocations.should eq([:callback_1, :callback_2])
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'invokes each of the :before_foo callbacks with no tag' do
|
83
|
+
subject.before_foo { invocations << :no_tag_1 }
|
84
|
+
subject.before_foo { invocations << :no_tag_2 }
|
85
|
+
|
86
|
+
subject.invoke_hook(:before_foo, :green)
|
87
|
+
invocations.should eq([:no_tag_1, :no_tag_2])
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'does not invoke any callbacks with a different tag' do
|
91
|
+
subject.before_foo(:blue) { invocations << :blue_callback }
|
92
|
+
subject.invoke_tagged_hook(:before_foo, :green)
|
93
|
+
invocations.should be_empty
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'passes along the provided arguments to the callback' do
|
97
|
+
subject.before_foo(:green, &lambda { |a, b| invocations << [a, b] })
|
98
|
+
subject.invoke_tagged_hook(:before_foo, :green, :arg1, :arg2)
|
99
|
+
invocations.flatten.should eq([:arg1, :arg2])
|
90
100
|
end
|
91
101
|
end
|
92
102
|
end
|