vcr 2.2.5 → 2.3.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.
Files changed (45) hide show
  1. data/.gitignore +5 -0
  2. data/.travis.yml +0 -5
  3. data/Appraisals +9 -0
  4. data/CHANGELOG.md +21 -0
  5. data/Gemfile +17 -21
  6. data/README.md +5 -2
  7. data/Rakefile +1 -0
  8. data/features/configuration/hook_into.feature +7 -6
  9. data/features/configuration/uri_parser.feature +91 -0
  10. data/features/middleware/faraday.feature +4 -3
  11. data/features/support/http_lib_filters.rb +2 -3
  12. data/features/support/vcr_cucumber_helpers.rb +2 -1
  13. data/features/test_frameworks/cucumber.feature +6 -0
  14. data/gemfiles/typhoeus-new.gemfile +18 -0
  15. data/gemfiles/typhoeus-new.gemfile.lock +172 -0
  16. data/gemfiles/typhoeus-old.gemfile +18 -0
  17. data/gemfiles/typhoeus-old.gemfile.lock +159 -0
  18. data/lib/vcr/cassette/migrator.rb +1 -1
  19. data/lib/vcr/configuration.rb +28 -0
  20. data/lib/vcr/errors.rb +1 -1
  21. data/lib/vcr/library_hooks/typhoeus.rb +74 -77
  22. data/lib/vcr/library_hooks/typhoeus_0.4.rb +99 -0
  23. data/lib/vcr/middleware/faraday.rb +1 -1
  24. data/lib/vcr/request_ignorer.rb +2 -2
  25. data/lib/vcr/request_matcher_registry.rb +8 -3
  26. data/lib/vcr/structs.rb +8 -1
  27. data/lib/vcr/test_frameworks/cucumber.rb +1 -1
  28. data/lib/vcr/version.rb +1 -1
  29. data/script/ci.sh +8 -1
  30. data/spec/capture_warnings.rb +10 -0
  31. data/spec/monkey_patches.rb +21 -3
  32. data/spec/spec_helper.rb +2 -0
  33. data/spec/support/http_library_adapters.rb +29 -0
  34. data/spec/support/limited_uri.rb +30 -0
  35. data/spec/support/vcr_localhost_server.rb +1 -4
  36. data/spec/vcr/cassette/http_interaction_list_spec.rb +0 -1
  37. data/spec/vcr/configuration_spec.rb +15 -1
  38. data/spec/vcr/library_hooks/typhoeus_0.4_spec.rb +31 -0
  39. data/spec/vcr/library_hooks/typhoeus_spec.rb +6 -6
  40. data/spec/vcr/library_hooks/webmock_spec.rb +3 -1
  41. data/spec/vcr/middleware/faraday_spec.rb +3 -1
  42. data/spec/vcr/request_matcher_registry_spec.rb +3 -1
  43. data/spec/vcr/structs_spec.rb +27 -1
  44. data/spec/vcr/test_frameworks/cucumber_spec.rb +1 -1
  45. metadata +41 -29
@@ -2,7 +2,7 @@ require 'faraday'
2
2
  require 'vcr/util/version_checker'
3
3
  require 'vcr/request_handler'
4
4
 
5
- VCR::VersionChecker.new('Faraday', Faraday::VERSION, '0.7.0', '0.8').check_version!
5
+ VCR::VersionChecker.new('Faraday', Faraday::VERSION, '0.7.0', '0.9').check_version!
6
6
 
7
7
  module VCR
8
8
  # Contains middlewares for use with different libraries.
@@ -1,4 +1,3 @@
1
- require 'uri'
2
1
  require 'set'
3
2
  require 'vcr/util/hooks'
4
3
 
@@ -13,7 +12,8 @@ module VCR
13
12
 
14
13
  def initialize
15
14
  ignore_request do |request|
16
- ignored_hosts.include?(URI(request.uri).host)
15
+ host = request.parsed_uri.host
16
+ ignored_hosts.include?(host)
17
17
  end
18
18
  end
19
19
 
@@ -18,7 +18,7 @@ module VCR
18
18
  # @private
19
19
  class URIWithoutParamsMatcher < Struct.new(:params_to_ignore)
20
20
  def partial_uri_from(request)
21
- URI(request.uri).tap do |uri|
21
+ request.parsed_uri.tap do |uri|
22
22
  return request.uri unless uri.query # ignore uris without params, e.g. "http://example.com/"
23
23
 
24
24
  uri.query = uri.query.split('&').tap { |params|
@@ -109,10 +109,15 @@ module VCR
109
109
  def register_built_ins
110
110
  register(:method) { |r1, r2| r1.method == r2.method }
111
111
  register(:uri) { |r1, r2| r1.uri == r2.uri }
112
- register(:host) { |r1, r2| URI(r1.uri).host == URI(r2.uri).host }
113
- register(:path) { |r1, r2| URI(r1.uri).path == URI(r2.uri).path }
114
112
  register(:body) { |r1, r2| r1.body == r2.body }
115
113
  register(:headers) { |r1, r2| r1.headers == r2.headers }
114
+
115
+ register(:host) do |r1, r2|
116
+ r1.parsed_uri.host == r2.parsed_uri.host
117
+ end
118
+ register(:path) do |r1, r2|
119
+ r1.parsed_uri.path == r2.parsed_uri.path
120
+ end
116
121
  end
117
122
  end
118
123
  end
@@ -231,6 +231,13 @@ module VCR
231
231
  :skip_port_stripping
232
232
  end
233
233
 
234
+ # Parses the URI using the configured `uri_parser`.
235
+ #
236
+ # @return [#schema, #host, #port, #path, #query] A parsed URI object.
237
+ def parsed_uri
238
+ VCR.configuration.uri_parser.parse(uri)
239
+ end
240
+
234
241
  @@object_method = Object.instance_method(:method)
235
242
  def method(*args)
236
243
  return super if args.empty?
@@ -321,7 +328,7 @@ module VCR
321
328
 
322
329
  def without_standard_port(uri)
323
330
  return uri if uri.nil?
324
- u = URI(uri)
331
+ u = parsed_uri
325
332
  return uri unless [['http', 80], ['https', 443]].include?([u.scheme, u.port])
326
333
  u.port = nil
327
334
  u.to_s
@@ -43,7 +43,7 @@ module VCR
43
43
  feature = scenario.respond_to?(:scenario_outline) ? scenario.scenario_outline.feature : scenario.feature
44
44
  name = feature.name.split("\n").first
45
45
  name << "/#{scenario.scenario_outline.name}" if scenario.respond_to?(:scenario_outline)
46
- name << "/#{scenario.name}"
46
+ name << "/#{scenario.name.split("\n").first}"
47
47
  name
48
48
  else
49
49
  "cucumber_tags/#{tag_name.gsub(/\A@/, '')}"
@@ -10,7 +10,7 @@ module VCR
10
10
  # * `parts` [Array<Integer>] List of the version parts.
11
11
  def version
12
12
  @version ||= begin
13
- string = '2.2.5'
13
+ string = '2.3.0'
14
14
 
15
15
  def string.parts
16
16
  split('.').map { |p| p.to_i }
@@ -1,14 +1,21 @@
1
1
  # Kill the whole script on error
2
- set -e
2
+ set -e -x
3
+
4
+ echo "-------- Running Typhoeus 0.4 Specs ---------"
5
+ bundle install --gemfile=gemfiles/typhoeus-old.gemfile
6
+ BUNDLE_GEMFILE=gemfiles/typhoeus-old.gemfile bundle exec rspec spec/vcr/library_hooks/typhoeus_0.4_spec.rb --format progress --backtrace
3
7
 
4
8
  # Setup vendored rspec-1
5
9
  git submodule init
6
10
  git submodule update
7
11
 
12
+ echo "-------- Running Specs ---------"
8
13
  bundle exec ruby -w -I./spec -r./spec/capture_warnings -rspec_helper -S rspec spec --format progress --backtrace
9
14
 
15
+ echo "-------- Running Cukes ---------"
10
16
  bundle exec cucumber
11
17
 
18
+ echo "-------- Checking Coverage ---------"
12
19
  bundle exec rake yard_coverage
13
20
 
14
21
  bundle exec rake check_code_coverage
@@ -31,6 +31,16 @@ RSpec.configure do |config|
31
31
  end
32
32
  end
33
33
 
34
+ # For some reason, I get a strange warning on 1.9.2 on Travis-CI but
35
+ # I can't repro locally:
36
+ # from /home/travis/builds/myronmarston/vcr/spec/monkey_pnet/http:
37
+ # warning: Content-Type did not set; using application/x-www-form-urlencoded
38
+ if RUBY_VERSION == '1.9.2' && ENV['CI']
39
+ vcr_warnings.reject! do |line|
40
+ line.include?('monkey_pnet')
41
+ end
42
+ end
43
+
34
44
  if vcr_warnings.any?
35
45
  puts
36
46
  puts "-" * 30 + " VCR Warnings: " + "-" * 30
@@ -1,4 +1,4 @@
1
- require 'typhoeus' unless RUBY_INTERPRETER == :jruby
1
+ require 'typhoeus' if RUBY_INTERPRETER == :mri
2
2
 
3
3
  module MonkeyPatches
4
4
  extend self
@@ -28,6 +28,14 @@ module MonkeyPatches
28
28
  ::WebMock::CallbackRegistry.add_callback(cb[:options], cb[:block])
29
29
  end
30
30
  when :typhoeus
31
+ $original_typhoeus_global_hooks.each do |hook|
32
+ ::Typhoeus.on_complete << hook
33
+ end
34
+ ::Typhoeus.before.clear
35
+ $original_typhoeus_before_hooks.each do |hook|
36
+ ::Typhoeus.before << hook
37
+ end
38
+ when :typhoeus_0_4
31
39
  ::Typhoeus::Hydra.global_hooks = $original_typhoeus_global_hooks
32
40
  ::Typhoeus::Hydra.stub_finders.clear
33
41
  $original_typhoeus_stub_finders.each do |finder|
@@ -55,7 +63,10 @@ module MonkeyPatches
55
63
  ::WebMock::StubRegistry.instance.request_stubs = []
56
64
  end
57
65
 
58
- if defined?(::Typhoeus)
66
+ if defined?(::Typhoeus.before)
67
+ ::Typhoeus.on_complete.clear
68
+ ::Typhoeus.before.clear
69
+ elsif defined?(::Typhoeus::Hydra)
59
70
  ::Typhoeus::Hydra.clear_global_hooks
60
71
  ::Typhoeus::Hydra.stub_finders.clear
61
72
  end
@@ -130,7 +141,14 @@ unless RUBY_INTERPRETER == :jruby
130
141
  require 'patron'
131
142
  require 'em-http-request'
132
143
  require 'curb'
144
+ end
133
145
 
146
+ if defined?(::Typhoeus.before)
147
+ require 'vcr/library_hooks/typhoeus'
148
+ $typhoeus_after_loaded_hook = VCR.configuration.hooks[:after_library_hooks_loaded].last
149
+ $original_typhoeus_global_hooks = Typhoeus.on_complete.dup
150
+ $original_typhoeus_before_hooks = Typhoeus.before.dup
151
+ elsif defined?(::Typhoeus::Hydra.global_hooks)
134
152
  require 'vcr/library_hooks/typhoeus'
135
153
  $typhoeus_after_loaded_hook = VCR.configuration.hooks[:after_library_hooks_loaded].last
136
154
  $original_typhoeus_global_hooks = Typhoeus::Hydra.global_hooks.dup
@@ -159,7 +177,7 @@ $original_excon_stubs = ::Excon.stubs.dup
159
177
  MonkeyPatches.disable_all!
160
178
 
161
179
  RSpec.configure do |config|
162
- [:fakeweb, :webmock, :vcr, :typhoeus, :excon].each do |scope|
180
+ [:fakeweb, :webmock, :vcr, :typhoeus, :typhoeus_0_4, :excon].each do |scope|
163
181
  config.before(:all, :with_monkey_patches => scope) { MonkeyPatches.enable!(scope) }
164
182
  config.after(:all, :with_monkey_patches => scope) { MonkeyPatches.disable_all! }
165
183
  end
@@ -29,6 +29,7 @@ end
29
29
  require 'rspec'
30
30
 
31
31
  require "support/fixnum_extension.rb"
32
+ require "support/limited_uri.rb"
32
33
  require "support/http_library_adapters.rb"
33
34
  require "support/ruby_interpreter.rb"
34
35
  require "support/shared_example_groups/hook_into_http_library.rb"
@@ -62,6 +63,7 @@ RSpec.configure do |config|
62
63
  unless example.metadata[:skip_vcr_reset]
63
64
  VCR.reset!
64
65
  VCR.configuration.cassette_library_dir = tmp_dir
66
+ VCR.configuration.uri_parser = LimitedURI
65
67
  end
66
68
  end
67
69
 
@@ -159,6 +159,29 @@ HTTP_LIBRARY_ADAPTERS['typhoeus'] = Module.new do
159
159
  end
160
160
  alias get_body_object get_body_string
161
161
 
162
+ def get_header(header_key, response)
163
+ response.headers[header_key]
164
+ end
165
+
166
+ def make_http_request(method, url, body = nil, headers = {})
167
+ request = Typhoeus::Request.new(url, :method => method, :body => body, :headers => headers)
168
+ request.run
169
+ request.response
170
+ end
171
+
172
+ def normalize_request_headers(headers)
173
+ headers.merge("User-Agent"=>["Typhoeus - https://github.com/typhoeus/typhoeus"])
174
+ end
175
+ end
176
+
177
+ HTTP_LIBRARY_ADAPTERS['typhoeus 0.4'] = Module.new do
178
+ def self.http_library_name; "Typhoeus"; end
179
+
180
+ def get_body_string(response)
181
+ response.body
182
+ end
183
+ alias get_body_object get_body_string
184
+
162
185
  def get_header(header_key, response)
163
186
  response.headers_hash[header_key]
164
187
  end
@@ -196,6 +219,12 @@ HTTP_LIBRARY_ADAPTERS['excon'] = Module.new do
196
219
  end
197
220
 
198
221
  %w[ net_http typhoeus patron ].each do |_faraday_adapter|
222
+ if _faraday_adapter == 'typhoeus' &&
223
+ defined?(::Typhoeus::VERSION) &&
224
+ ::Typhoeus::VERSION.to_f >= 0.5
225
+ require 'typhoeus/adapters/faraday'
226
+ end
227
+
199
228
  HTTP_LIBRARY_ADAPTERS["faraday (w/ #{_faraday_adapter})"] = Module.new do
200
229
  class << self; self; end.class_eval do
201
230
  define_method(:http_library_name) do
@@ -0,0 +1,30 @@
1
+ require 'forwardable'
2
+
3
+ class LimitedURI
4
+ extend Forwardable
5
+
6
+ def_delegators :@uri, :scheme,
7
+ :host,
8
+ :port,
9
+ :port=,
10
+ :path,
11
+ :query,
12
+ :query=,
13
+ :to_s
14
+
15
+ def initialize(uri)
16
+ @uri = uri
17
+ end
18
+
19
+ def ==(other)
20
+ to_s == other.to_s
21
+ end
22
+
23
+ def self.parse(uri)
24
+ return uri if uri.is_a? LimitedURI
25
+ return new(uri) if uri.is_a? URI
26
+ return new(URI.parse(uri)) if uri.is_a? String
27
+
28
+ raise URI::InvalidURIError
29
+ end
30
+ end
@@ -81,10 +81,7 @@ module VCR
81
81
  end
82
82
 
83
83
  def should_use_subprocess?
84
- # Patron times out when the server is running in a separate thread in the same process,
85
- # so use a separate process.
86
- # In all other cases, we can use a thread (it's faster!)
87
- defined?(Patron)
84
+ false
88
85
  end
89
86
 
90
87
  def wait_until(timeout, error_message, &block)
@@ -2,7 +2,6 @@ require 'vcr/util/logger'
2
2
  require 'vcr/cassette/http_interaction_list'
3
3
  require 'vcr/request_matcher_registry'
4
4
  require 'vcr/structs'
5
- require 'uri'
6
5
 
7
6
  module VCR
8
7
  class Cassette
@@ -102,10 +102,12 @@ describe VCR::Configuration do
102
102
  end
103
103
 
104
104
  describe '#ignore_request' do
105
+ let(:uri){ URI('http://foo.com') }
106
+
105
107
  it 'registers the given block with the request ignorer' do
106
108
  block_called = false
107
109
  subject.ignore_request { |r| block_called = true }
108
- VCR.request_ignorer.ignore?(stub(:uri => 'http://foo.com/'))
110
+ VCR.request_ignorer.ignore?(stub(:parsed_uri => uri))
109
111
  block_called.should be_true
110
112
  end
111
113
  end
@@ -250,6 +252,18 @@ describe VCR::Configuration do
250
252
  end
251
253
  end
252
254
 
255
+ describe "#uri_parser=" do
256
+ let(:custom_parser) { stub }
257
+ it 'allows a custom uri parser to be set' do
258
+ subject.uri_parser = custom_parser
259
+ subject.uri_parser.should eq(custom_parser)
260
+ end
261
+
262
+ it "uses Ruby's standard library `URI` as a default" do
263
+ subject.uri_parser.should eq(URI)
264
+ end
265
+ end
266
+
253
267
  describe "#preserve_exact_body_bytes_for?" do
254
268
  def message_for(body)
255
269
  stub(:body => body)
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Typhoeus 0.4 hook", :with_monkey_patches => :typhoeus_0_4 do
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 0.4'
23
+
24
+ describe "VCR.configuration.after_library_hooks_loaded hook" do
25
+ it 'disables the webmock typhoeus adapter so it does not conflict with our typhoeus hook' do
26
+ ::WebMock::HttpLibAdapters::TyphoeusAdapter.should_receive(:disable!)
27
+ $typhoeus_after_loaded_hook.conditionally_invoke
28
+ end
29
+ end
30
+ end if RUBY_INTERPRETER == :mri && ::Typhoeus::VERSION.to_f < 0.5
31
+
@@ -2,21 +2,21 @@ 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
5
+ ::Typhoeus::Expectation.clear
6
6
  end
7
7
 
8
8
  def disable_real_connections
9
- ::Typhoeus::Hydra.allow_net_connect = false
10
- ::Typhoeus::Hydra::NetConnectNotAllowedError
9
+ ::Typhoeus::Config.block_connection = true
10
+ ::Typhoeus::Errors::NoStub
11
11
  end
12
12
 
13
13
  def enable_real_connections
14
- ::Typhoeus::Hydra.allow_net_connect = true
14
+ ::Typhoeus::Config.block_connection = false
15
15
  end
16
16
 
17
17
  def directly_stub_request(method, url, response_body)
18
18
  response = ::Typhoeus::Response.new(:code => 200, :body => response_body)
19
- ::Typhoeus::Hydra.stub(method, url).and_return(response)
19
+ ::Typhoeus.stub(url, :method => method).and_return(response)
20
20
  end
21
21
 
22
22
  it_behaves_like 'a hook into an HTTP library', :typhoeus, 'typhoeus'
@@ -27,5 +27,5 @@ describe "Typhoeus hook", :with_monkey_patches => :typhoeus do
27
27
  $typhoeus_after_loaded_hook.conditionally_invoke
28
28
  end
29
29
  end
30
- end unless RUBY_PLATFORM == 'java'
30
+ end
31
31
 
@@ -69,7 +69,9 @@ describe "WebMock hook", :with_monkey_patches => :webmock do
69
69
  end
70
70
  end
71
71
 
72
- %w[net/http patron httpclient em-http-request curb typhoeus excon].each do |lib|
72
+ http_libs = %w[net/http patron httpclient em-http-request curb typhoeus excon]
73
+ http_libs.delete('patron') if RUBY_VERSION == '1.8.7'
74
+ http_libs.each do |lib|
73
75
  other = []
74
76
  other << :status_message_not_exposed if lib == 'excon'
75
77
  it_behaves_like 'a hook into an HTTP library', :webmock, lib, *other do
@@ -2,7 +2,9 @@ require 'spec_helper'
2
2
  require 'vcr/library_hooks/faraday'
3
3
 
4
4
  describe VCR::Middleware::Faraday do
5
- %w[ typhoeus net_http patron ].each do |lib|
5
+ http_libs = %w[ typhoeus net_http patron ]
6
+ http_libs.delete('patron') if RUBY_VERSION == '1.8.7'
7
+ http_libs.each do |lib|
6
8
  it_behaves_like 'a hook into an HTTP library', :faraday, "faraday (w/ #{lib})",
7
9
  :status_message_not_exposed,
8
10
  :does_not_support_rotating_responses,
@@ -1,9 +1,11 @@
1
1
  require 'vcr/request_matcher_registry'
2
2
  require 'vcr/structs'
3
- require 'uri'
3
+ require 'support/limited_uri'
4
4
 
5
5
  module VCR
6
6
  describe RequestMatcherRegistry do
7
+ before { VCR.stub_chain(:configuration, :uri_parser) { LimitedURI } }
8
+
7
9
  def request_with(values)
8
10
  VCR::Request.new.tap do |request|
9
11
  values.each do |name, value|
@@ -7,7 +7,7 @@ require 'vcr/structs'
7
7
  require 'vcr/errors'
8
8
  require 'zlib'
9
9
  require 'stringio'
10
- require 'uri'
10
+ require 'support/limited_uri'
11
11
 
12
12
  shared_examples_for "a header normalizer" do
13
13
  let(:instance) do
@@ -61,6 +61,8 @@ end
61
61
 
62
62
  module VCR
63
63
  describe HTTPInteraction do
64
+ before { VCR.stub_chain(:configuration, :uri_parser) { LimitedURI } }
65
+
64
66
  if ''.respond_to?(:encoding)
65
67
  def body_hash(key, value)
66
68
  { key => value, 'encoding' => 'UTF-8' }
@@ -235,6 +237,7 @@ module VCR
235
237
  describe "#to_hash" do
236
238
  before(:each) do
237
239
  VCR.stub_chain(:configuration, :preserve_exact_body_bytes_for?).and_return(false)
240
+ VCR.stub_chain(:configuration, :uri_parser).and_return(URI)
238
241
  end
239
242
 
240
243
  let(:hash) { interaction.to_hash }
@@ -289,9 +292,30 @@ module VCR
289
292
  assert_yielded_keys hash['response']['status'], 'code', 'message'
290
293
  end
291
294
  end
295
+
296
+ describe "#parsed_uri" do
297
+ before :each do
298
+ uri_parser.stub(:parse).and_return(uri)
299
+ VCR.stub_chain(:configuration, :uri_parser).and_return(uri_parser)
300
+ end
301
+
302
+ let(:uri_parser){ mock('parser') }
303
+ let(:uri){ mock('uri').as_null_object }
304
+
305
+ it "parses the uri using the current uri_parser" do
306
+ uri_parser.should_receive(:parse).with(request.uri)
307
+ request.parsed_uri
308
+ end
309
+
310
+ it "returns the parsed uri" do
311
+ request.parsed_uri.should == uri
312
+ end
313
+ end
292
314
  end
293
315
 
294
316
  describe HTTPInteraction::HookAware do
317
+ before { VCR.stub_chain(:configuration, :uri_parser) { LimitedURI } }
318
+
295
319
  let(:response_status) { VCR::ResponseStatus.new(200, "OK foo") }
296
320
  let(:body) { "The body foo this is (foo-Foo)" }
297
321
  let(:headers) do {
@@ -431,6 +455,8 @@ module VCR
431
455
  end
432
456
 
433
457
  describe Request do
458
+ before { VCR.stub_chain(:configuration, :uri_parser) { LimitedURI } }
459
+
434
460
  describe '#method' do
435
461
  subject { VCR::Request.new(:get) }
436
462