vcr 2.5.0 → 2.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 (79) hide show
  1. checksums.yaml +8 -8
  2. data/.travis.yml +0 -3
  3. data/CHANGELOG.md +32 -3
  4. data/Gemfile +33 -0
  5. data/Gemfile.lock +99 -119
  6. data/README.md +19 -7
  7. data/Rakefile +5 -9
  8. data/benchmarks/null_logging.rb +62 -0
  9. data/features/.nav +0 -1
  10. data/features/about_these_examples.md +1 -2
  11. data/features/cassettes/allow_unused_http_interactions.feature +15 -1
  12. data/features/cassettes/decompress.feature +6 -2
  13. data/features/cassettes/format.feature +20 -12
  14. data/features/cassettes/freezing_time.feature +68 -0
  15. data/features/configuration/cassette_library_dir.feature +5 -0
  16. data/features/configuration/preserve_exact_body_bytes.feature +5 -0
  17. data/features/configuration/uri_parser.feature +2 -4
  18. data/features/http_libraries/net_http.feature +1 -1
  19. data/features/request_matching/headers.feature +0 -1
  20. data/features/step_definitions/cli_steps.rb +1 -4
  21. data/features/test_frameworks/cucumber.feature +59 -0
  22. data/features/test_frameworks/rspec_metadata.feature +59 -1
  23. data/gemfiles/typhoeus_old.gemfile +19 -0
  24. data/gemfiles/typhoeus_old.gemfile.lock +84 -86
  25. data/lib/vcr.rb +12 -3
  26. data/lib/vcr/cassette.rb +32 -11
  27. data/lib/vcr/cassette/http_interaction_list.rb +3 -2
  28. data/lib/vcr/cassette/migrator.rb +1 -0
  29. data/lib/vcr/cassette/serializers/json.rb +1 -1
  30. data/lib/vcr/configuration.rb +17 -9
  31. data/lib/vcr/library_hooks/typhoeus.rb +3 -2
  32. data/lib/vcr/library_hooks/webmock.rb +1 -1
  33. data/lib/vcr/middleware/excon.rb +13 -1
  34. data/lib/vcr/middleware/faraday.rb +1 -0
  35. data/lib/vcr/request_handler.rb +1 -1
  36. data/lib/vcr/structs.rb +19 -4
  37. data/lib/vcr/test_frameworks/cucumber.rb +2 -2
  38. data/lib/vcr/test_frameworks/rspec.rb +10 -2
  39. data/lib/vcr/util/logger.rb +41 -7
  40. data/lib/vcr/version.rb +1 -1
  41. data/script/ci.sh +8 -1
  42. data/spec/acceptance/threading_spec.rb +6 -0
  43. data/spec/capture_warnings.rb +9 -1
  44. data/spec/spec_helper.rb +6 -2
  45. data/spec/support/configuration_stubbing.rb +8 -0
  46. data/spec/support/http_library_adapters.rb +1 -1
  47. data/spec/support/limited_uri.rb +1 -0
  48. data/spec/support/shared_example_groups/excon.rb +23 -1
  49. data/spec/support/shared_example_groups/hook_into_http_library.rb +12 -12
  50. data/spec/support/shared_example_groups/request_hooks.rb +1 -1
  51. data/spec/support/sinatra_app.rb +9 -0
  52. data/spec/support/vcr_localhost_server.rb +4 -25
  53. data/spec/support/vcr_stub_helpers.rb +1 -1
  54. data/spec/vcr/cassette/http_interaction_list_spec.rb +41 -14
  55. data/spec/vcr/cassette/migrator_spec.rb +1 -1
  56. data/spec/vcr/cassette/persisters_spec.rb +2 -2
  57. data/spec/vcr/cassette/serializers_spec.rb +13 -4
  58. data/spec/vcr/cassette_spec.rb +107 -58
  59. data/spec/vcr/configuration_spec.rb +23 -23
  60. data/spec/vcr/deprecations_spec.rb +9 -9
  61. data/spec/vcr/errors_spec.rb +6 -6
  62. data/spec/vcr/library_hooks/excon_spec.rb +15 -10
  63. data/spec/vcr/library_hooks/fakeweb_spec.rb +8 -8
  64. data/spec/vcr/library_hooks/faraday_spec.rb +1 -1
  65. data/spec/vcr/library_hooks/typhoeus_0.4_spec.rb +2 -2
  66. data/spec/vcr/library_hooks/typhoeus_spec.rb +68 -9
  67. data/spec/vcr/library_hooks/webmock_spec.rb +6 -10
  68. data/spec/vcr/middleware/faraday_spec.rb +33 -5
  69. data/spec/vcr/middleware/rack_spec.rb +2 -2
  70. data/spec/vcr/request_matcher_registry_spec.rb +11 -6
  71. data/spec/vcr/structs_spec.rb +114 -47
  72. data/spec/vcr/test_frameworks/cucumber_spec.rb +4 -4
  73. data/spec/vcr/util/hooks_spec.rb +2 -2
  74. data/spec/vcr/util/internet_connection_spec.rb +3 -3
  75. data/spec/vcr/util/version_checker_spec.rb +4 -4
  76. data/spec/vcr_spec.rb +22 -16
  77. data/vcr.gemspec +2 -31
  78. metadata +9 -328
  79. data/features/test_frameworks/shoulda.feature +0 -64
@@ -5,7 +5,7 @@ Feature: Usage with RSpec metadata
5
5
 
6
6
  Once you've done that, you can have an example group or example use
7
7
  VCR by passing `:vcr` as an additional argument after the description
8
- string. It will use set the cassette name based on the example's
8
+ string. It will set the cassette name based on the example's
9
9
  full description.
10
10
 
11
11
  If you need to override the cassette name or options, you can pass a
@@ -28,6 +28,31 @@ Feature: Usage with RSpec metadata
28
28
  c.treat_symbols_as_metadata_keys_with_true_values = true
29
29
  end
30
30
  """
31
+ And a previously recorded cassette file "spec/cassettes/Group/optionally_raises_an_error.yml" with:
32
+ """
33
+ ---
34
+ http_interactions:
35
+ - request:
36
+ method: get
37
+ uri: http://example.com/foo
38
+ body:
39
+ encoding: UTF-8
40
+ string: ""
41
+ headers: {}
42
+ response:
43
+ status:
44
+ code: 200
45
+ message: OK
46
+ headers:
47
+ Content-Length:
48
+ - "5"
49
+ body:
50
+ encoding: UTF-8
51
+ string: Hello
52
+ http_version: "1.1"
53
+ recorded_at: Tue, 01 Nov 2011 04:58:44 GMT
54
+ recorded_with: VCR 2.0.0
55
+ """
31
56
 
32
57
  Scenario: Use `:vcr` metadata
33
58
  Given a file named "spec/vcr_example_spec.rb" with:
@@ -71,6 +96,39 @@ Feature: Usage with RSpec metadata
71
96
  And the file "spec/cassettes/VCR_example_group_metadata/in_a_nested_example_group/records_another_one.yml" should contain "Hello"
72
97
  And the file "spec/cassettes/VCR_example_metadata/records_an_http_request.yml" should contain "Hello"
73
98
 
99
+ Scenario: `:allow_unused_http_interactions => false` causes a failure if there are unused interactions
100
+ And a file named "spec/vcr_example_spec.rb" with:
101
+ """ruby
102
+ require 'spec_helper'
103
+
104
+ describe "Group", :vcr => { :allow_unused_http_interactions => false } do
105
+ it 'optionally raises an error' do
106
+ # don't fail
107
+ end
108
+ end
109
+ """
110
+ When I run `rspec spec/vcr_example_spec.rb`
111
+ Then it should fail with an error like:
112
+ """
113
+ There are unused HTTP interactions left in the cassette:
114
+ - [get http://example.com/foo] => [200 "Hello"]
115
+ """
116
+
117
+ Scenario: `:allow_unused_http_interactions => false` does not raise if the example already failed
118
+ And a file named "spec/vcr_example_spec.rb" with:
119
+ """ruby
120
+ require 'spec_helper'
121
+
122
+ describe "Group", :vcr => { :allow_unused_http_interactions => false } do
123
+ it 'optionally raises an error' do
124
+ raise "boom"
125
+ end
126
+ end
127
+ """
128
+ When I run `rspec spec/vcr_example_spec.rb`
129
+ Then it should fail with "boom"
130
+ And the output should not contain "There are unused HTTP interactions"
131
+
74
132
  Scenario: Pass a hash to set the cassette options
75
133
  Given a file named "spec/vcr_example_spec.rb" with:
76
134
  """ruby
@@ -10,6 +10,25 @@ gem "fuubar"
10
10
  gem "fuubar-cucumber"
11
11
  gem "redcarpet", "~> 1.17.2", :platforms=>:ruby
12
12
  gem "github-markup"
13
+ gem "rake", ">= 0.9.2"
14
+ gem "cucumber", ">= 1.1.4"
15
+ gem "aruba", ">= 0.5"
16
+ gem "rspec", ">= 2.11"
17
+ gem "fakeweb", ">= 1.3.0"
18
+ gem "faraday", ">= 0.8"
19
+ gem "httpclient", ">= 2.2"
20
+ gem "excon", ">= 0.22"
21
+ gem "timecop", "0.6.1"
22
+ gem "rack", ">= 1.3.6"
23
+ gem "sinatra", ">= 1.3.2"
24
+ gem "multi_json", ">= 1.0.3"
25
+ gem "json", ">= 1.6.5"
26
+ gem "simplecov", ">= 0.5.3"
27
+ gem "redis", ">= 2.2.2"
28
+ gem "patron", ">= 0.4.15", :platform=>:ruby
29
+ gem "em-http-request", ">= 1.0.2", :platform=>:ruby
30
+ gem "curb", ">= 0.8.0", :platform=>:ruby
31
+ gem "yajl-ruby", ">= 1.1.0", :platform=>:ruby
13
32
  gem "typhoeus", "~> 0.4.2"
14
33
  gem "webmock", "1.8.11"
15
34
 
@@ -1,99 +1,99 @@
1
1
  PATH
2
2
  remote: /Users/myron/code/vcr
3
3
  specs:
4
- vcr (2.4.0)
4
+ vcr (2.5.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- addressable (2.3.3)
10
- appraisal (0.5.1)
9
+ addressable (2.3.5)
10
+ appraisal (0.5.2)
11
11
  bundler
12
12
  rake
13
13
  archive-tar-minitar (0.5.2)
14
- aruba (0.4.11)
15
- childprocess (>= 0.2.3)
14
+ aruba (0.5.3)
15
+ childprocess (>= 0.3.6)
16
16
  cucumber (>= 1.1.1)
17
- ffi (>= 1.0.11)
18
- rspec (>= 2.7.0)
19
- builder (3.2.0)
17
+ rspec-expectations (>= 2.7.0)
18
+ builder (3.2.2)
20
19
  childprocess (0.3.9)
21
20
  ffi (~> 1.0, >= 1.0.11)
22
21
  cookiejar (0.3.0)
23
- crack (0.3.2)
24
- cucumber (1.1.9)
22
+ crack (0.4.1)
23
+ safe_yaml (~> 0.9.0)
24
+ cucumber (1.3.8)
25
25
  builder (>= 2.1.2)
26
- diff-lcs (>= 1.1.2)
27
- gherkin (~> 2.9.0)
28
- json (>= 1.4.6)
29
- term-ansicolor (>= 1.0.6)
30
- curb (0.8.3)
31
- diff-lcs (1.2.1)
32
- em-http-request (1.0.3)
33
- addressable (>= 2.2.3)
26
+ diff-lcs (>= 1.1.3)
27
+ gherkin (~> 2.12.1)
28
+ multi_json (>= 1.7.5, < 2.0)
29
+ multi_test (>= 0.0.2)
30
+ curb (0.8.4)
31
+ diff-lcs (1.2.4)
32
+ em-http-request (1.1.0)
33
+ addressable (>= 2.3.4)
34
34
  cookiejar
35
- em-socksify
36
- eventmachine (>= 1.0.0.beta.4)
37
- http_parser.rb (>= 0.5.3)
38
- em-socksify (0.2.1)
35
+ em-socksify (>= 0.3)
36
+ eventmachine (>= 1.0.3)
37
+ http_parser.rb (>= 0.6.0.beta.2)
38
+ em-socksify (0.3.0)
39
39
  eventmachine (>= 1.0.0.beta.4)
40
- eventmachine (1.0.1)
41
- excon (0.20.0)
40
+ eventmachine (1.0.3)
41
+ excon (0.25.3)
42
42
  fakeweb (1.3.0)
43
- faraday (0.8.6)
44
- multipart-post (~> 1.1)
45
- ffi (1.3.1)
46
- fuubar (1.0.0)
43
+ faraday (0.8.8)
44
+ multipart-post (~> 1.2.0)
45
+ ffi (1.9.0)
46
+ fuubar (1.2.1)
47
47
  rspec (~> 2.0)
48
48
  rspec-instafail (~> 0.2.0)
49
- ruby-progressbar (~> 0.0.10)
50
- fuubar-cucumber (0.0.15)
51
- cucumber (>= 1.0.2)
52
- ruby-progressbar (~> 0.0.10)
53
- gherkin (2.9.3)
54
- json (>= 1.4.6)
49
+ ruby-progressbar (~> 1.0)
50
+ fuubar-cucumber (0.0.20)
51
+ cucumber (~> 1.3.0)
52
+ ruby-progressbar (~> 1.0.0)
53
+ gherkin (2.12.1)
54
+ multi_json (~> 1.3)
55
55
  github-markup (0.7.5)
56
- http_parser.rb (0.5.3)
57
- httpclient (2.3.3)
58
- json (1.6.8)
59
- mime-types (1.21)
60
- multi_json (1.0.4)
56
+ http_parser.rb (0.6.0.beta.2)
57
+ httpclient (2.3.4.1)
58
+ json (1.8.0)
59
+ mime-types (1.25)
60
+ multi_json (1.8.0)
61
+ multi_test (0.0.2)
61
62
  multipart-post (1.2.0)
62
63
  patron (0.4.18)
63
- rack (1.3.10)
64
- rack-protection (1.4.0)
64
+ rack (1.5.2)
65
+ rack-protection (1.5.0)
65
66
  rack
66
- rake (0.9.6)
67
+ rake (10.1.0)
67
68
  redcarpet (1.17.2)
68
- redis (2.2.2)
69
- relish (0.6)
69
+ redis (3.0.4)
70
+ relish (0.7)
70
71
  archive-tar-minitar (>= 0.5.2)
71
72
  json (>= 1.4.6)
72
73
  rest-client (>= 1.6.1)
73
74
  rest-client (1.6.7)
74
75
  mime-types (>= 1.16)
75
- rspec (2.13.0)
76
- rspec-core (~> 2.13.0)
77
- rspec-expectations (~> 2.13.0)
78
- rspec-mocks (~> 2.13.0)
79
- rspec-core (2.13.0)
80
- rspec-expectations (2.13.0)
76
+ rspec (2.14.1)
77
+ rspec-core (~> 2.14.0)
78
+ rspec-expectations (~> 2.14.0)
79
+ rspec-mocks (~> 2.14.0)
80
+ rspec-core (2.14.5)
81
+ rspec-expectations (2.14.2)
81
82
  diff-lcs (>= 1.1.3, < 2.0)
82
83
  rspec-instafail (0.2.4)
83
- rspec-mocks (2.13.0)
84
- ruby-progressbar (0.0.10)
85
- shoulda (2.9.2)
86
- simplecov (0.5.4)
87
- multi_json (~> 1.0.3)
88
- simplecov-html (~> 0.5.3)
89
- simplecov-html (0.5.3)
90
- sinatra (1.3.3)
91
- rack (~> 1.3, >= 1.3.6)
92
- rack-protection (~> 1.2)
93
- tilt (~> 1.3, >= 1.3.3)
94
- term-ansicolor (1.0.7)
95
- tilt (1.3.4)
96
- timecop (0.3.5)
84
+ rspec-mocks (2.14.3)
85
+ ruby-progressbar (1.0.2)
86
+ safe_yaml (0.9.7)
87
+ simplecov (0.7.1)
88
+ multi_json (~> 1.0)
89
+ simplecov-html (~> 0.7.1)
90
+ simplecov-html (0.7.1)
91
+ sinatra (1.4.3)
92
+ rack (~> 1.4)
93
+ rack-protection (~> 1.4)
94
+ tilt (~> 1.3, >= 1.3.4)
95
+ tilt (1.4.1)
96
+ timecop (0.6.1)
97
97
  typhoeus (0.4.2)
98
98
  ffi (~> 1.0)
99
99
  mime-types (~> 1.18)
@@ -101,41 +101,39 @@ GEM
101
101
  addressable (>= 2.2.7)
102
102
  crack (>= 0.1.7)
103
103
  yajl-ruby (1.1.0)
104
- yard (0.8.5.2)
104
+ yard (0.8.7.2)
105
105
 
106
106
  PLATFORMS
107
107
  ruby
108
108
 
109
109
  DEPENDENCIES
110
110
  appraisal
111
- aruba (~> 0.4.11)
112
- bundler (>= 1.0.7)
113
- cucumber (~> 1.1.4)
114
- curb (~> 0.8.0)
115
- em-http-request (~> 1.0.2)
116
- excon (>= 0.11.0, < 1.0)
117
- fakeweb (~> 1.3.0)
118
- faraday (~> 0.8)
111
+ aruba (>= 0.5)
112
+ cucumber (>= 1.1.4)
113
+ curb (>= 0.8.0)
114
+ em-http-request (>= 1.0.2)
115
+ excon (>= 0.22)
116
+ fakeweb (>= 1.3.0)
117
+ faraday (>= 0.8)
119
118
  fuubar
120
119
  fuubar-cucumber
121
120
  github-markup
122
- httpclient (~> 2.2)
121
+ httpclient (>= 2.2)
123
122
  jruby-openssl
124
- json (~> 1.6.5)
125
- multi_json (~> 1.0.3)
126
- patron (~> 0.4.15)
127
- rack (~> 1.3.6)
128
- rake (~> 0.9.2)
123
+ json (>= 1.6.5)
124
+ multi_json (>= 1.0.3)
125
+ patron (>= 0.4.15)
126
+ rack (>= 1.3.6)
127
+ rake (>= 0.9.2)
129
128
  redcarpet (~> 1.17.2)
130
- redis (~> 2.2.2)
129
+ redis (>= 2.2.2)
131
130
  relish (~> 0.6)
132
- rspec (~> 2.11)
133
- shoulda (~> 2.9.2)
134
- simplecov (~> 0.5.3)
135
- sinatra (~> 1.3.2)
136
- timecop (~> 0.3.5)
131
+ rspec (>= 2.11)
132
+ simplecov (>= 0.5.3)
133
+ sinatra (>= 1.3.2)
134
+ timecop (= 0.6.1)
137
135
  typhoeus (~> 0.4.2)
138
136
  vcr!
139
137
  webmock (= 1.8.11)
140
- yajl-ruby (~> 1.1.0)
138
+ yajl-ruby (>= 1.1.0)
141
139
  yard
data/lib/vcr.rb CHANGED
@@ -88,7 +88,10 @@ module VCR
88
88
  # @option options :allow_unused_http_interactions [Boolean] If set to
89
89
  # false, an error will be raised if a cassette is ejected before all
90
90
  # previously recorded HTTP interactions have been used.
91
- # Defaults to true.
91
+ # Defaults to true. Note that when an error has already occurred
92
+ # (as indicated by the `$!` variable) unused interactions will be
93
+ # allowed so that we don't silence the original error (which is almost
94
+ # certainly more interesting/important).
92
95
  # @option options :exclusive [Boolean] Whether or not to use only this
93
96
  # cassette and to completely ignore any cassettes in the cassettes stack.
94
97
  # Defaults to false.
@@ -134,10 +137,16 @@ module VCR
134
137
  # In addition, any newly recorded HTTP interactions will be written to
135
138
  # disk.
136
139
  #
140
+ # @param options [Hash] Eject options.
141
+ # @option options :skip_no_unused_interactions_assertion [Boolean]
142
+ # If `true` is given, this will skip the "no unused HTTP interactions"
143
+ # assertion enabled by the `:allow_unused_http_interactions => false`
144
+ # cassette option. This is intended for use when your test has had
145
+ # an error, but your test framework has already handled it.
137
146
  # @return [VCR::Cassette, nil] the ejected cassette if there was one
138
- def eject_cassette
147
+ def eject_cassette(options = {})
139
148
  cassette = cassettes.last
140
- cassette.eject if cassette
149
+ cassette.eject(options) if cassette
141
150
  cassette
142
151
  ensure
143
152
  cassettes.pop
data/lib/vcr/cassette.rb CHANGED
@@ -5,7 +5,7 @@ require 'vcr/cassette/serializers'
5
5
  module VCR
6
6
  # The media VCR uses to store HTTP interactions for later re-use.
7
7
  class Cassette
8
- include Logger
8
+ include Logger::Mixin
9
9
 
10
10
  # The supported record modes.
11
11
  #
@@ -56,9 +56,17 @@ module VCR
56
56
  # Ejects the current cassette. The cassette will no longer be used.
57
57
  # In addition, any newly recorded HTTP interactions will be written to
58
58
  # disk.
59
- def eject
59
+ #
60
+ # @note This is not intended to be called directly. Use `VCR.eject_cassette` instead.
61
+ #
62
+ # @param (see VCR#eject_casssette)
63
+ # @see VCR#eject_cassette
64
+ def eject(options = {})
60
65
  write_recorded_interactions_to_disk
61
- http_interactions.assert_no_unused_interactions! unless @allow_unused_http_interactions
66
+
67
+ if should_assert_no_unused_interactions? && !options[:skip_no_unused_interactions_assertion]
68
+ http_interactions.assert_no_unused_interactions!
69
+ end
62
70
  end
63
71
 
64
72
  # @private
@@ -110,6 +118,20 @@ module VCR
110
118
  }
111
119
  end
112
120
 
121
+ # @return [Time, nil] The `recorded_at` time of the first HTTP interaction
122
+ # or nil if the cassette has no prior HTTP interactions.
123
+ #
124
+ # @example
125
+ #
126
+ # VCR.use_cassette("some cassette") do |cassette|
127
+ # Timecop.freeze(cassette.originally_recorded_at || Time.now) do
128
+ # # ...
129
+ # end
130
+ # end
131
+ def originally_recorded_at
132
+ @originally_recorded_at ||= previously_recorded_interactions.map(&:recorded_at).min
133
+ end
134
+
113
135
  private
114
136
 
115
137
  def assert_valid_options!
@@ -174,13 +196,12 @@ module VCR
174
196
 
175
197
  def should_re_record?
176
198
  return false unless @re_record_interval
177
- previously_recorded_at = earliest_interaction_recorded_at
178
- return false unless previously_recorded_at
199
+ return false unless originally_recorded_at
179
200
 
180
201
  now = Time.now
181
202
 
182
- (previously_recorded_at + @re_record_interval < now).tap do |value|
183
- info = "previously recorded at: '#{previously_recorded_at}'; now: '#{now}'; interval: #{@re_record_interval} seconds"
203
+ (originally_recorded_at + @re_record_interval < now).tap do |value|
204
+ info = "previously recorded at: '#{originally_recorded_at}'; now: '#{now}'; interval: #{@re_record_interval} seconds"
184
205
 
185
206
  if !value
186
207
  log "Not re-recording since the interval has not elapsed (#{info})."
@@ -193,10 +214,6 @@ module VCR
193
214
  end
194
215
  end
195
216
 
196
- def earliest_interaction_recorded_at
197
- previously_recorded_interactions.map(&:recorded_at).min
198
- end
199
-
200
217
  def should_stub_requests?
201
218
  record_mode != :all
202
219
  end
@@ -205,6 +222,10 @@ module VCR
205
222
  record_mode == :all
206
223
  end
207
224
 
225
+ def should_assert_no_unused_interactions?
226
+ !(@allow_unused_http_interactions || $!)
227
+ end
228
+
208
229
  def raw_cassette_bytes
209
230
  @raw_cassette_bytes ||= VCR::Cassette::ERBRenderer.new(@persister[storage_key], erb, name).render
210
231
  end