vcr 2.2.5 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
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