vcr 1.5.1 → 1.6.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 (49) hide show
  1. data/CHANGELOG.md +11 -1
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +4 -3
  4. data/benchmarks/http_stubbing_libraries.rb +4 -4
  5. data/features/.nav +1 -0
  6. data/features/configuration/ignore_hosts.feature +61 -0
  7. data/features/http_libraries/net_http.feature +34 -0
  8. data/features/step_definitions/cli_steps.rb +16 -1
  9. data/lib/vcr.rb +23 -14
  10. data/lib/vcr/cassette.rb +2 -4
  11. data/lib/vcr/config.rb +20 -5
  12. data/lib/vcr/deprecations.rb +27 -14
  13. data/lib/vcr/http_stubbing_adapters/fakeweb.rb +14 -9
  14. data/lib/vcr/http_stubbing_adapters/faraday.rb +12 -3
  15. data/lib/vcr/http_stubbing_adapters/typhoeus.rb +3 -7
  16. data/lib/vcr/http_stubbing_adapters/webmock.rb +17 -7
  17. data/lib/vcr/middleware/faraday.rb +1 -1
  18. data/lib/vcr/request_matcher.rb +12 -8
  19. data/lib/vcr/structs/http_interaction.rb +16 -0
  20. data/lib/vcr/structs/normalizers/body.rb +24 -0
  21. data/lib/vcr/structs/normalizers/header.rb +56 -0
  22. data/lib/vcr/structs/normalizers/status_message.rb +17 -0
  23. data/lib/vcr/structs/normalizers/uri.rb +34 -0
  24. data/lib/vcr/structs/request.rb +20 -0
  25. data/lib/vcr/structs/response.rb +16 -0
  26. data/lib/vcr/structs/response_status.rb +9 -0
  27. data/lib/vcr/util/regexes.rb +37 -0
  28. data/lib/vcr/version.rb +16 -5
  29. data/spec/spec_helper.rb +26 -3
  30. data/spec/support/http_library_adapters.rb +11 -12
  31. data/spec/support/http_stubbing_adapter.rb +2 -16
  32. data/spec/support/normalizers.rb +84 -0
  33. data/spec/support/version_checker.rb +1 -1
  34. data/spec/vcr/cassette_spec.rb +8 -10
  35. data/spec/vcr/config_spec.rb +63 -17
  36. data/spec/vcr/deprecations_spec.rb +83 -24
  37. data/spec/vcr/http_stubbing_adapters/multi_object_proxy_spec.rb +1 -1
  38. data/spec/vcr/http_stubbing_adapters/typhoeus_spec.rb +2 -2
  39. data/spec/vcr/middleware/faraday_spec.rb +1 -1
  40. data/spec/vcr/structs/http_interaction_spec.rb +23 -0
  41. data/spec/vcr/structs/request_spec.rb +54 -0
  42. data/spec/vcr/structs/response_spec.rb +39 -0
  43. data/spec/vcr/structs/response_status_spec.rb +18 -0
  44. data/spec/vcr_spec.rb +26 -54
  45. data/vcr.gemspec +1 -1
  46. metadata +48 -31
  47. data/TODO.md +0 -5
  48. data/lib/vcr/structs.rb +0 -176
  49. data/spec/vcr/structs_spec.rb +0 -201
@@ -2,7 +2,17 @@
2
2
 
3
3
  ## In git
4
4
 
5
- [Full Changelog](http://github.com/myronmarston/vcr/compare/v1.5.1...master)
5
+ [Full Changelog](http://github.com/myronmarston/vcr/compare/v1.6.0...master)
6
+
7
+ ## 1.6.0 (February 3, 2011)
8
+
9
+ [Full Changelog](http://github.com/myronmarston/vcr/compare/v1.5.1...v1.6.0)
10
+
11
+ * Add new `ignore_hosts` configuration option that allows you to ignore
12
+ any host (not just localhost aliases, as the `ignore_localhost` option
13
+ works). Feature suggested by [Claudio Poli](https://github.com/masterkain).
14
+ * Upgraded to the latest Typhoeus (0.2.1).
15
+ * General code clean up and refactoring.
6
16
 
7
17
  ## 1.5.1 (January 12, 2011)
8
18
 
data/Gemfile CHANGED
@@ -7,7 +7,7 @@ group :development do
7
7
  gem 'patron', '~> 0.4.6'
8
8
  gem 'em-http-request', '~> 0.2.7'
9
9
  gem 'curb', '~> 0.7.8'
10
- gem 'typhoeus', '~> 0.2.0'
10
+ gem 'typhoeus', '~> 0.2.1'
11
11
  end
12
12
 
13
13
  platforms :jruby do
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- vcr (1.5.1)
4
+ vcr (1.6.0)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
@@ -113,7 +113,8 @@ GEM
113
113
  thor (0.14.6)
114
114
  tilt (1.1)
115
115
  timecop (0.3.5)
116
- typhoeus (0.2.0)
116
+ typhoeus (0.2.1)
117
+ mime-types
117
118
  webmock (1.6.2)
118
119
  addressable (>= 2.2.2)
119
120
  crack (>= 0.1.7)
@@ -149,6 +150,6 @@ DEPENDENCIES
149
150
  shoulda (~> 2.9.2)
150
151
  sinatra (~> 1.1.0)
151
152
  timecop (~> 0.3.5)
152
- typhoeus (~> 0.2.0)
153
+ typhoeus (~> 0.2.1)
153
154
  vcr!
154
155
  webmock (~> 1.6.0)
@@ -50,10 +50,10 @@ end
50
50
  # Output on my machine:
51
51
  #
52
52
  # Benchmarking Single setup/teardown:
53
- # webmock 0.000000 0.000000 8.500000 ( 8.559143)
54
- # fakeweb 0.000000 0.000000 1.900000 ( 1.967160)
53
+ # webmock 0.000000 0.000000 6.950000 ( 6.981525)
54
+ # fakeweb 0.000000 0.010000 1.750000 ( 1.740679)
55
55
  #
56
56
  #
57
57
  # Benchmarking Setup/teardown for each http request:
58
- # webmock 0.000000 0.000000 9.710000 ( 9.764760)
59
- # fakeweb 0.000000 0.000000 2.470000 ( 2.479292)
58
+ # webmock 0.000000 0.000000 7.970000 ( 7.981383)
59
+ # fakeweb 0.000000 0.000000 2.210000 ( 2.203478)
@@ -12,6 +12,7 @@
12
12
  - cassette_library_dir.feature
13
13
  - stub_with.feature
14
14
  - default_cassette_options.feature
15
+ - ignore_hosts.feature
15
16
  - ignore_localhost.feature
16
17
  - hooks.feature
17
18
  - allow_http_connections_when_no_cassette.feature
@@ -0,0 +1,61 @@
1
+ Feature: ignore_hosts
2
+
3
+ The `ignore_hosts` configuration option can be used to prevent VCR
4
+ from having any affect on requests to particular hosts.
5
+ Requests to ignored hosts will not be recorded and will always be
6
+ allowed, regardless of the record mode, and even outside of a
7
+ `VCR.use_cassette` block.
8
+
9
+ If you only want to ignore localhost (and its various aliases) you
10
+ may want to use the `ignore_localhost` option instead.
11
+
12
+ Background:
13
+ Given a file named "sinatra_app.rb" with:
14
+ """
15
+ require 'vcr_cucumber_helpers'
16
+
17
+ response_count = 0
18
+ start_sinatra_app(:port => 7777) do
19
+ get('/') { "Response #{response_count += 1}" }
20
+ end
21
+ """
22
+
23
+ Scenario Outline: ignored host requests are not recorded and are always allowed
24
+ Given a file named "ignore_hosts.rb" with:
25
+ """
26
+ require 'vcr_cucumber_helpers'
27
+ include_http_adapter_for("<http_lib>")
28
+ require 'sinatra_app.rb'
29
+
30
+ require 'vcr'
31
+
32
+ VCR.config do |c|
33
+ c.ignore_hosts '127.0.0.1', 'localhost'
34
+ c.cassette_library_dir = 'cassettes'
35
+ c.stub_with <stub_with>
36
+ end
37
+
38
+ VCR.use_cassette('example', :record => :new_episodes) do
39
+ puts response_body_for(:get, "http://localhost:7777/")
40
+ end
41
+
42
+ puts response_body_for(:get, "http://localhost:7777/")
43
+ """
44
+ When I run "ruby ignore_hosts.rb"
45
+ Then it should pass with:
46
+ """
47
+ Response 1
48
+ Response 2
49
+ """
50
+ And the file "cassettes/example.yml" should not exist
51
+
52
+ Examples:
53
+ | stub_with | http_lib |
54
+ | :fakeweb | net/http |
55
+ | :webmock | net/http |
56
+ | :webmock | httpclient |
57
+ | :webmock | patron |
58
+ | :webmock | curb |
59
+ | :webmock | em-http-request |
60
+ | :typhoeus | typhoeus |
61
+
@@ -135,3 +135,37 @@ Feature: Net::HTTP
135
135
  | stub_with |
136
136
  | :fakeweb |
137
137
  | :webmock |
138
+
139
+ Scenario Outline: Make an HTTPS request
140
+ Given a file named "vcr_https.rb" with:
141
+ """
142
+ require 'vcr'
143
+
144
+ VCR.config do |c|
145
+ c.stub_with <stub_with>
146
+ c.cassette_library_dir = 'cassettes'
147
+ end
148
+
149
+ uri = URI("https://gist.github.com/raw/fb555cb593f3349d53af/6921dd638337d3f6a51b0e02e7f30e3c414f70d6/vcr_gist")
150
+
151
+ VCR.use_cassette('https', :record => :new_episodes) do
152
+ http = Net::HTTP.new(uri.host, uri.port)
153
+ http.use_ssl = true
154
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
155
+ response = http.request_get(uri.path)
156
+
157
+ puts response.body
158
+ end
159
+ """
160
+ When I run "ruby vcr_https.rb"
161
+ Then the output should contain "VCR gist"
162
+ And the file "cassettes/https.yml" should contain "body: VCR gist"
163
+
164
+ When I modify the file "cassettes/https.yml" to replace "body: VCR gist" with "body: HTTPS replaying works"
165
+ And I run "ruby vcr_https.rb"
166
+ Then the output should contain "HTTPS replaying works"
167
+
168
+ Examples:
169
+ | stub_with |
170
+ | :fakeweb |
171
+ | :webmock |
@@ -1,4 +1,4 @@
1
- require 'vcr/structs'
1
+ require 'vcr'
2
2
 
3
3
  module VCRHelpers
4
4
  YAML_REGEX_FOR_1_9_1 = Regexp.union(*[
@@ -36,6 +36,17 @@ module VCRHelpers
36
36
 
37
37
  structs
38
38
  end
39
+
40
+ def modify_file(file_name, orig_text, new_text)
41
+ in_current_dir do
42
+ file = File.read(file_name)
43
+ regex = /#{Regexp.escape(orig_text)}/
44
+ file.should =~ regex
45
+
46
+ file = file.gsub(regex, new_text)
47
+ File.open(file_name, 'w') { |f| f.write(file) }
48
+ end
49
+ end
39
50
  end
40
51
  World(VCRHelpers)
41
52
 
@@ -55,6 +66,10 @@ Given /^(\d+) days have passed since the cassette was recorded$/ do |day_count|
55
66
  set_env('DAYS_PASSED', day_count)
56
67
  end
57
68
 
69
+ When /^I modify the file "([^"]*)" to replace "([^"]*)" with "([^"]*)"$/ do |file_name, orig_text, new_text|
70
+ modify_file(file_name, orig_text, new_text)
71
+ end
72
+
58
73
  Then /^the file "([^"]*)" should exist$/ do |file_name|
59
74
  check_file_presence([file_name], true)
60
75
  end
data/lib/vcr.rb CHANGED
@@ -2,10 +2,19 @@ require 'vcr/cassette'
2
2
  require 'vcr/config'
3
3
  require 'vcr/deprecations'
4
4
  require 'vcr/request_matcher'
5
- require 'vcr/structs'
5
+ require 'vcr/util/regexes'
6
6
  require 'vcr/version'
7
7
  require 'vcr/http_stubbing_adapters/common'
8
8
 
9
+ require 'vcr/structs/normalizers/body'
10
+ require 'vcr/structs/normalizers/header'
11
+ require 'vcr/structs/normalizers/status_message'
12
+ require 'vcr/structs/normalizers/uri'
13
+ require 'vcr/structs/http_interaction'
14
+ require 'vcr/structs/request'
15
+ require 'vcr/structs/response'
16
+ require 'vcr/structs/response_status'
17
+
9
18
  module VCR
10
19
  extend self
11
20
 
@@ -65,7 +74,7 @@ module VCR
65
74
  yield VCR::Config
66
75
  http_stubbing_adapter.check_version!
67
76
  http_stubbing_adapter.set_http_connections_allowed_to_default
68
- http_stubbing_adapter.ignore_localhost = VCR::Config.ignore_localhost?
77
+ http_stubbing_adapter.ignored_hosts = VCR::Config.ignored_hosts
69
78
  end
70
79
 
71
80
  def cucumber_tags(&block)
@@ -79,16 +88,7 @@ module VCR
79
88
  raise ArgumentError.new("You have configured VCR to use both :fakeweb and :webmock. You cannot use both.")
80
89
  end
81
90
 
82
- adapters = VCR::Config.http_stubbing_libraries.map do |lib|
83
- case lib
84
- when :fakeweb; HttpStubbingAdapters::FakeWeb
85
- when :webmock; HttpStubbingAdapters::WebMock
86
- when :typhoeus; HttpStubbingAdapters::Typhoeus
87
- when :faraday; HttpStubbingAdapters::Faraday
88
- else raise ArgumentError.new("#{lib.inspect} is not a supported HTTP stubbing library.")
89
- end
90
- end
91
-
91
+ adapters = VCR::Config.http_stubbing_libraries.map { |l| adapter_for(l) }
92
92
  raise ArgumentError.new("The http stubbing library is not configured.") if adapters.empty?
93
93
  HttpStubbingAdapters::MultiObjectProxy.for(*adapters)
94
94
  end
@@ -96,8 +96,7 @@ module VCR
96
96
 
97
97
  def record_http_interaction(interaction)
98
98
  return unless cassette = current_cassette
99
- return if http_stubbing_adapter.ignore_localhost? &&
100
- LOCALHOST_ALIASES.include?(URI.parse(interaction.uri).host)
99
+ return if VCR::Config.uri_should_be_ignored?(interaction.uri)
101
100
 
102
101
  cassette.record_http_interaction(interaction)
103
102
  end
@@ -132,6 +131,16 @@ module VCR
132
131
 
133
132
  private
134
133
 
134
+ def adapter_for(lib)
135
+ case lib
136
+ when :fakeweb; HttpStubbingAdapters::FakeWeb
137
+ when :webmock; HttpStubbingAdapters::WebMock
138
+ when :typhoeus; HttpStubbingAdapters::Typhoeus
139
+ when :faraday; HttpStubbingAdapters::Faraday
140
+ else raise ArgumentError.new("#{lib.inspect} is not a supported HTTP stubbing library.")
141
+ end
142
+ end
143
+
135
144
  def cassettes
136
145
  @cassettes ||= []
137
146
  end
@@ -104,10 +104,8 @@ module VCR
104
104
  interactions = YAML.load(raw_yaml_content)
105
105
  invoke_hook(:before_playback, interactions)
106
106
 
107
- if VCR.http_stubbing_adapter.ignore_localhost?
108
- interactions.reject! do |i|
109
- i.uri.is_a?(String) && VCR::LOCALHOST_ALIASES.include?(URI.parse(i.uri).host)
110
- end
107
+ interactions.reject! do |i|
108
+ i.request.uri.is_a?(String) && VCR::Config.uri_should_be_ignored?(i.request.uri)
111
109
  end
112
110
 
113
111
  recorded_interactions.replace(interactions)
@@ -30,13 +30,22 @@ module VCR
30
30
  @http_stubbing_libraries ||= []
31
31
  end
32
32
 
33
- def ignore_localhost=(value)
34
- @ignore_localhost = value
35
- VCR.http_stubbing_adapter.ignore_localhost = value if http_stubbing_libraries.any?
33
+ def ignore_hosts(*hosts)
34
+ ignored_hosts.push(*hosts).uniq!
35
+ VCR.http_stubbing_adapter.ignored_hosts = ignored_hosts if http_stubbing_libraries.any?
36
+ end
37
+ alias ignore_host ignore_hosts
38
+
39
+ def ignored_hosts
40
+ @ignored_hosts ||= []
36
41
  end
37
42
 
38
- def ignore_localhost?
39
- @ignore_localhost
43
+ def ignore_localhost=(value)
44
+ if value
45
+ ignore_hosts *VCR::LOCALHOST_ALIASES
46
+ else
47
+ ignored_hosts.reject! { |h| VCR::LOCALHOST_ALIASES.include?(h) }
48
+ end
40
49
  end
41
50
 
42
51
  def allow_http_connections_when_no_cassette=(value)
@@ -47,5 +56,11 @@ module VCR
47
56
  def allow_http_connections_when_no_cassette?
48
57
  !!@allow_http_connections_when_no_cassette
49
58
  end
59
+
60
+ def uri_should_be_ignored?(uri)
61
+ uri = URI.parse(uri) unless uri.respond_to?(:host)
62
+ ignored_hosts.include?(uri.host)
63
+ end
50
64
  end
51
65
  end
66
+
@@ -1,22 +1,33 @@
1
1
  module VCR
2
- module Config
3
- class << self
4
- def http_stubbing_library
5
- warn "WARNING: `VCR::Config.http_stubbing_library` is deprecated. Use `VCR::Config.http_stubbing_libraries` instead."
6
- @http_stubbing_libraries && @http_stubbing_libraries.first
2
+ module HttpStubbingAdapters
3
+ module Common
4
+ def ignore_localhost?
5
+ VCR::Config.ignore_localhost?
7
6
  end
7
+ end
8
+ end
8
9
 
9
- def http_stubbing_library=(library)
10
- warn "WARNING: `VCR::Config.http_stubbing_library = #{library.inspect}` is deprecated. Use `VCR::Config.stub_with #{library.inspect}` instead."
11
- stub_with library
12
- end
10
+ module Config
11
+ def http_stubbing_library
12
+ warn "WARNING: `VCR::Config.http_stubbing_library` is deprecated. Use `VCR::Config.http_stubbing_libraries` instead."
13
+ @http_stubbing_libraries && @http_stubbing_libraries.first
14
+ end
15
+
16
+ def http_stubbing_library=(library)
17
+ warn "WARNING: `VCR::Config.http_stubbing_library = #{library.inspect}` is deprecated. Use `VCR::Config.stub_with #{library.inspect}` instead."
18
+ stub_with library
19
+ end
20
+
21
+ def ignore_localhost?
22
+ warn "WARNING: `VCR::Config.ignore_localhost?` is deprecated. Check the list of ignored hosts using `VCR::Config.ignored_hosts` instead."
23
+ (VCR::LOCALHOST_ALIASES - ignored_hosts).empty?
13
24
  end
14
25
  end
15
26
 
16
27
  class Cassette
17
28
  def allow_real_http_requests_to?(uri)
18
29
  warn "WARNING: VCR::Cassette#allow_real_http_requests_to? is deprecated and should no longer be used."
19
- VCR.http_stubbing_adapter.ignore_localhost? && VCR::LOCALHOST_ALIASES.include?(uri.host)
30
+ VCR::Config.uri_should_be_ignored?(uri.to_s)
20
31
  end
21
32
 
22
33
  private
@@ -24,8 +35,9 @@ module VCR
24
35
  def deprecate_old_cassette_options(options)
25
36
  message = "VCR's :allow_real_http cassette option is deprecated. Instead, use the ignore_localhost configuration option."
26
37
  if options[:allow_real_http] == :localhost
27
- @original_ignore_localhost = VCR.http_stubbing_adapter.ignore_localhost?
28
- VCR.http_stubbing_adapter.ignore_localhost = true
38
+ @original_ignored_hosts = VCR::Config.ignored_hosts.dup
39
+ VCR::Config.ignored_hosts.clear
40
+ VCR::Config.ignore_hosts *VCR::LOCALHOST_ALIASES
29
41
  Kernel.warn "WARNING: #{message}"
30
42
  elsif options[:allow_real_http]
31
43
  raise ArgumentError.new(message)
@@ -33,8 +45,9 @@ module VCR
33
45
  end
34
46
 
35
47
  def restore_ignore_localhost_for_deprecation
36
- if defined?(@original_ignore_localhost)
37
- VCR.http_stubbing_adapter.ignore_localhost = @original_ignore_localhost
48
+ if defined?(@original_ignored_hosts)
49
+ VCR::Config.ignored_hosts.clear
50
+ VCR::Config.ignore_hosts *@original_ignored_hosts
38
51
  end
39
52
  end
40
53
  end
@@ -8,7 +8,6 @@ module VCR
8
8
  extend self
9
9
 
10
10
  UNSUPPORTED_REQUEST_MATCH_ATTRIBUTES = [:body, :headers]
11
- LOCALHOST_REGEX = %r|\Ahttps?://((\w+:)?\w+@)?(#{VCR::LOCALHOST_ALIASES.map { |a| Regexp.escape(a) }.join('|')})(:\d+)?/|i
12
11
 
13
12
  MINIMUM_VERSION = '1.3.0'
14
13
  MAXIMUM_VERSION = '1.3'
@@ -22,15 +21,11 @@ module VCR
22
21
  !!::FakeWeb.allow_net_connect?("http://some.url/besides/localhost")
23
22
  end
24
23
 
25
- def ignore_localhost=(value)
26
- @ignore_localhost = value
24
+ def ignored_hosts=(hosts)
25
+ @ignored_hosts = hosts
27
26
  update_fakeweb_allow_net_connect
28
27
  end
29
28
 
30
- def ignore_localhost?
31
- !!@ignore_localhost
32
- end
33
-
34
29
  def stub_requests(http_interactions, match_attributes)
35
30
  validate_match_attributes(match_attributes)
36
31
 
@@ -62,6 +57,10 @@ module VCR
62
57
 
63
58
  private
64
59
 
60
+ def ignored_hosts
61
+ @ignored_hosts ||= []
62
+ end
63
+
65
64
  def version
66
65
  ::FakeWeb::VERSION
67
66
  end
@@ -69,8 +68,8 @@ module VCR
69
68
  def update_fakeweb_allow_net_connect
70
69
  ::FakeWeb.allow_net_connect = if @http_connections_allowed
71
70
  true
72
- elsif @ignore_localhost
73
- LOCALHOST_REGEX
71
+ elsif ignored_hosts.any?
72
+ VCR::Regexes.url_regex_for_hosts(ignored_hosts)
74
73
  else
75
74
  false
76
75
  end
@@ -93,6 +92,12 @@ module VCR
93
92
  raise UnsupportedRequestMatchAttributeError.new("FakeWeb does not support matching requests on #{invalid_attributes.join(' or ')}")
94
93
  end
95
94
  end
95
+
96
+ def self.const_missing(const)
97
+ return super unless const == :LOCALHOST_REGEX
98
+ warn "WARNING: `VCR::HttpStubbingAdapters::FakeWeb::LOCALHOST_REGEX` is deprecated."
99
+ VCR::Regexes.url_regex_for_hosts(VCR::LOCALHOST_ALIASES)
100
+ end
96
101
  end
97
102
  end
98
103
  end