vcr 2.5.0 → 2.6.0

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