vcr 1.5.1 → 1.6.0

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