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
data/Rakefile CHANGED
@@ -1,8 +1,8 @@
1
1
  using_git = File.exist?(File.expand_path('../.git/', __FILE__))
2
2
 
3
3
  if using_git
4
- require 'bundler'
5
4
  require 'bundler/setup'
5
+ require 'bundler/gem_helper'
6
6
  Bundler::GemHelper.install_tasks
7
7
  require 'appraisal'
8
8
  end
@@ -15,7 +15,7 @@ RSpec::Core::RakeTask.new(:spec) do |t|
15
15
 
16
16
  # we require spec_helper so we don't get an RSpec warning about
17
17
  # examples being defined before configuration.
18
- t.ruby_opts = "-w -I./spec -r./spec/capture_warnings -rspec_helper"
18
+ t.ruby_opts = "-I./spec -r./spec/capture_warnings -rspec_helper"
19
19
  t.rspec_opts = %w[--format progress] if (ENV['FULL_BUILD'] || !using_git)
20
20
  end
21
21
 
@@ -37,12 +37,12 @@ end
37
37
 
38
38
  desc "Checks the spec coverage and fails if it is less than 100%"
39
39
  task :check_code_coverage do
40
- if RUBY_VERSION < '1.9' || RUBY_ENGINE != 'ruby'
40
+ if RUBY_VERSION.to_f < 1.9 || RUBY_ENGINE != 'ruby'
41
41
  puts "Cannot check code coverage--simplecov is not supported on this platform"
42
42
  else
43
43
  percent = File.read("./coverage/coverage_percent.txt").to_f
44
44
  if percent < 98.0
45
- raise "Spec coverage was not high enough: #{percent.round(2)}%"
45
+ abort "Spec coverage was not high enough: #{percent.round(2)}%"
46
46
  else
47
47
  puts "Nice job! Spec coverage is still above 98%"
48
48
  end
@@ -103,11 +103,7 @@ task :prep_relish_release do
103
103
  ENV['NEW_RELISH_RELEASE'] = 'true'
104
104
  end
105
105
 
106
- task :require_ruby_18 do
107
- raise "This must be run on Ruby 1.8" unless RUBY_VERSION =~ /^1\.8/
108
- end
109
-
110
- task :release => [:require_ruby_18, :prep_relish_release, :relish]
106
+ task :release => [:prep_relish_release, :relish]
111
107
 
112
108
  # For gem-test: http://gem-testers.org/
113
109
  task :test => :spec
@@ -0,0 +1,62 @@
1
+ $LOAD_PATH.unshift "./lib"
2
+ require 'vcr'
3
+ require 'yaml'
4
+ require 'open-uri'
5
+ require 'benchmark'
6
+
7
+ VCR.configure do |vcr|
8
+ vcr.cassette_library_dir = './tmp'
9
+ vcr.hook_into :webmock
10
+ end
11
+
12
+ def prepare_cassette
13
+ interactions = 1.upto(100).map do |i|
14
+ VCR::HTTPInteraction.new(
15
+ VCR::Request.new(:get, "http://foo.com/#{i}", "", {}),
16
+ VCR::Response.new(
17
+ VCR::ResponseStatus.new(200, "OK"),
18
+ {}, "Response #{i}", "1.1"
19
+ ),
20
+ Time.now
21
+ ).to_hash
22
+ end
23
+
24
+ hash = { "http_interactions" => interactions, "recorded_with" => "VCR #{VCR.version}" }
25
+ VCR.cassette_persisters[:file_system]["logging.yml"] = YAML.dump(hash)
26
+ end
27
+
28
+ prepare_cassette
29
+
30
+ puts "Ruby #{RUBY_DESCRIPTION}"
31
+
32
+ 3.times do
33
+ puts Benchmark.measure {
34
+ 100.downto(50) do |i|
35
+ VCR.use_cassette("logging", :record => :none) do
36
+ open("http://foo.com/#{i}")
37
+ end
38
+ end
39
+ }
40
+ end
41
+
42
+ # Before optimizing null logging:
43
+ #
44
+ # Ruby ruby 1.9.3p448 (2013-06-27 revision 41675) [x86_64-darwin12.4.0]
45
+ # 1.510000 0.010000 1.520000 ( 1.523553)
46
+ # 1.500000 0.010000 1.510000 ( 1.510036)
47
+ # 1.500000 0.010000 1.510000 ( 1.507076)
48
+ #
49
+ # After applying the patch from #311 (and forcing `debug_logger` to `nil`:
50
+ #
51
+ # Ruby ruby 1.9.3p448 (2013-06-27 revision 41675) [x86_64-darwin12.4.0]
52
+ # 1.480000 0.020000 1.500000 ( 1.500136)
53
+ # 1.390000 0.000000 1.390000 ( 1.395503)
54
+ # 1.400000 0.010000 1.410000 ( 1.403931)
55
+ #
56
+ # After applying my alternate fix:
57
+ #
58
+ # Ruby ruby 1.9.3p448 (2013-06-27 revision 41675) [x86_64-darwin12.4.0]
59
+ # 1.400000 0.010000 1.410000 ( 1.410103)
60
+ # 1.380000 0.010000 1.390000 ( 1.388467)
61
+ # 1.360000 0.010000 1.370000 ( 1.364418)
62
+
data/features/.nav CHANGED
@@ -51,7 +51,6 @@
51
51
  - playback_repeats.feature
52
52
  - test_frameworks:
53
53
  - test_unit.feature
54
- - shoulda.feature
55
54
  - rspec_metadata.feature
56
55
  - rspec_macro.feature
57
56
  - cucumber.feature
@@ -15,5 +15,4 @@ provided by `vcr_cucumber_helpers.rb`:
15
15
  library.
16
16
 
17
17
  If you have ideas to clarify or improve any of these cucumber features,
18
- please submit an [issue](https://github.com/myronmarston/vcr/issues) or
19
- pull request.
18
+ please submit an [issue](https://github.com/vcr/vcr/issues) or pull request.
@@ -1,7 +1,8 @@
1
1
  Feature: Allow Unused HTTP Interactions
2
2
 
3
3
  If set to false, this cassette option will cause VCR to raise an error
4
- when a cassette is ejected and there are unused HTTP interactions remaining.
4
+ when a cassette is ejected and there are unused HTTP interactions remaining,
5
+ unless there is already an exception unwinding the callstack.
5
6
 
6
7
  It verifies that all requests included in the cassette were made, and allows
7
8
  VCR to function a bit like a mock object at the HTTP layer.
@@ -84,3 +85,16 @@ Feature: Allow Unused HTTP Interactions
84
85
  When I run `ruby disallowed_with_all_requests.rb`
85
86
  Then it should pass
86
87
 
88
+ Scenario: Does not silence other errors raised in `use_cassette` block
89
+ Given a file named "does_not_silence_other_errors.rb" with:
90
+ """ruby
91
+ require 'vcr_config'
92
+
93
+ VCR.use_cassette("example", :allow_unused_http_interactions => false) do
94
+ raise "boom"
95
+ end
96
+ """
97
+ When I run `ruby does_not_silence_other_errors.rb`
98
+ Then it should fail with "boom"
99
+ And the output should not contain "There are unused HTTP interactions"
100
+
@@ -41,7 +41,9 @@ Feature: Decode compressed response
41
41
  When I append to file "decompress.rb":
42
42
  """ruby
43
43
  VCR.use_cassette(:decompress) do
44
- Net::HTTP.get_response('localhost', '/', 7777)
44
+ Net::HTTP.start('localhost', 7777) do |http|
45
+ http.get('/', 'accept-encoding' => 'identity')
46
+ end
45
47
  end
46
48
  """
47
49
  And I run `ruby decompress.rb`
@@ -55,7 +57,9 @@ Feature: Decode compressed response
55
57
  When I append to file "decompress.rb":
56
58
  """ruby
57
59
  VCR.use_cassette(:decompress, :decode_compressed_response => true) do
58
- Net::HTTP.get_response('localhost', '/', 7777)
60
+ Net::HTTP.start('localhost', 7777) do |http|
61
+ http.get('/', 'accept-encoding' => 'identity')
62
+ end
59
63
  end
60
64
  """
61
65
  And I run `ruby decompress.rb`
@@ -69,8 +69,8 @@ Feature: Cassette format
69
69
  end
70
70
 
71
71
  VCR.use_cassette('example') do
72
- make_http_request(:get, "http://localhost:7777/foo")
73
- make_http_request(:get, "http://localhost:7777/bar")
72
+ make_http_request(:get, "http://localhost:7777/foo", nil, 'Accept-Encoding' => 'identity')
73
+ make_http_request(:get, "http://localhost:7777/bar", nil, 'Accept-Encoding' => 'identity')
74
74
  end
75
75
  """
76
76
  When I run `ruby cassette_yaml.rb 'Hello'`
@@ -84,7 +84,9 @@ Feature: Cassette format
84
84
  body:
85
85
  encoding: UTF-8
86
86
  string: ""
87
- headers: {}
87
+ headers:
88
+ Accept-Encoding:
89
+ - identity
88
90
  response:
89
91
  status:
90
92
  code: 200
@@ -105,7 +107,9 @@ Feature: Cassette format
105
107
  body:
106
108
  encoding: UTF-8
107
109
  string: ""
108
- headers: {}
110
+ headers:
111
+ Accept-Encoding:
112
+ - identity
109
113
  response:
110
114
  status:
111
115
  code: 200
@@ -153,8 +157,8 @@ Feature: Cassette format
153
157
  end
154
158
 
155
159
  VCR.use_cassette('example', :serialize_with => :json) do
156
- puts response_body_for(:get, "http://localhost:7777/foo")
157
- puts response_body_for(:get, "http://localhost:7777/bar")
160
+ puts response_body_for(:get, "http://localhost:7777/foo", nil, 'Accept-Encoding' => 'identity')
161
+ puts response_body_for(:get, "http://localhost:7777/bar", nil, 'Accept-Encoding' => 'identity')
158
162
  end
159
163
  """
160
164
  When I run `ruby cassette_json.rb 'Hello'`
@@ -185,7 +189,9 @@ Feature: Cassette format
185
189
  "string": ""
186
190
  },
187
191
  "method": "get",
188
- "headers": { }
192
+ "headers": {
193
+ "Accept-Encoding": [ "identity" ]
194
+ }
189
195
  },
190
196
  "recorded_at": "Tue, 01 Nov 2011 04:58:44 GMT"
191
197
  },
@@ -212,7 +218,9 @@ Feature: Cassette format
212
218
  "string": ""
213
219
  },
214
220
  "method": "get",
215
- "headers": { }
221
+ "headers": {
222
+ "Accept-Encoding": [ "identity" ]
223
+ }
216
224
  },
217
225
  "recorded_at": "Tue, 01 Nov 2011 04:58:44 GMT"
218
226
  }
@@ -254,8 +262,8 @@ Feature: Cassette format
254
262
  end
255
263
 
256
264
  VCR.use_cassette('example', :serialize_with => :ruby) do
257
- puts response_body_for(:get, "http://localhost:7777/foo")
258
- puts response_body_for(:get, "http://localhost:7777/bar")
265
+ puts response_body_for(:get, "http://localhost:7777/foo", nil, 'Accept-Encoding' => 'identity')
266
+ puts response_body_for(:get, "http://localhost:7777/bar", nil, 'Accept-Encoding' => 'identity')
259
267
  end
260
268
  """
261
269
  When I run `ruby cassette_ruby.rb 'Hello'`
@@ -266,7 +274,7 @@ Feature: Cassette format
266
274
  {"method"=>"get",
267
275
  "uri"=>"http://localhost:7777/foo",
268
276
  "body"=>{"encoding"=>"UTF-8", "string"=>""},
269
- "headers"=>{"Accept"=>["*/*"], "User-Agent"=>["Ruby"]}},
277
+ "headers"=>{"Accept"=>["*/*"], "Accept-Encoding"=>["identity"], "User-Agent"=>["Ruby"]}},
270
278
  "response"=>
271
279
  {"status"=>{"code"=>200, "message"=>"OK "},
272
280
  "headers"=>
@@ -280,7 +288,7 @@ Feature: Cassette format
280
288
  {"method"=>"get",
281
289
  "uri"=>"http://localhost:7777/bar",
282
290
  "body"=>{"encoding"=>"UTF-8", "string"=>""},
283
- "headers"=>{"Accept"=>["*/*"], "User-Agent"=>["Ruby"]}},
291
+ "headers"=>{"Accept"=>["*/*"], "Accept-Encoding"=>["identity"], "User-Agent"=>["Ruby"]}},
284
292
  "response"=>
285
293
  {"status"=>{"code"=>200, "message"=>"OK "},
286
294
  "headers"=>
@@ -0,0 +1,68 @@
1
+ Feature: Freezing Time
2
+
3
+ When dealing with an HTTP API that includes time-based compontents
4
+ in the request (e.g. for signed S3 requests), it can be useful
5
+ on playback to freeze time to what it originally was when the
6
+ cassette was recorded so that the request is always the same
7
+ each time your test is run.
8
+
9
+ While VCR doesn't directly support time freezing, it does
10
+ expose `VCR::Cassette#originally_recorded_at`, which you can
11
+ easily use with a library like
12
+ [timecop](https://github.com/travisjeffery/timecop)
13
+ to freeze time.
14
+
15
+ Note: `VCR::Cassette#originally_recorded_at` will return `nil`
16
+ when the cassette is recording for the first time, so you'll
17
+ probably want to use an expression like
18
+ `cassette.originally_recorded_at || Time.now` so that it
19
+ will work when recording or when playing back.
20
+
21
+ Scenario: Previously recorded responses are replayed
22
+ Given a previously recorded cassette file "cassettes/example.yml" with:
23
+ """
24
+ ---
25
+ http_interactions:
26
+ - request:
27
+ method: get
28
+ uri: http://example.com/events/since/2013-09-23T17:00:30Z
29
+ body:
30
+ encoding: UTF-8
31
+ string: ""
32
+ headers: {}
33
+ response:
34
+ status:
35
+ code: 200
36
+ message: OK
37
+ headers:
38
+ Content-Length:
39
+ - "20"
40
+ body:
41
+ encoding: UTF-8
42
+ string: Some Event
43
+ http_version: "1.1"
44
+ recorded_at: Mon, 23 Sep 2013 17:00:30 GMT
45
+ recorded_with: VCR 2.0.0
46
+ """
47
+ Given a file named "freeze_time.rb" with:
48
+ """ruby
49
+ require 'time'
50
+ require 'timecop'
51
+ require 'vcr'
52
+
53
+ VCR.configure do |vcr|
54
+ vcr.cassette_library_dir = 'cassettes'
55
+ vcr.hook_into :webmock
56
+ end
57
+
58
+ VCR.use_cassette('example') do |cassette|
59
+ Timecop.freeze(cassette.originally_recorded_at || Time.now) do
60
+ path = "/events/since/#{Time.now.getutc.iso8601}"
61
+ response = Net::HTTP.get_response('example.com', path)
62
+ puts "Response: #{response.body}"
63
+ end
64
+ end
65
+ """
66
+ When I run `ruby freeze_time.rb`
67
+ Then it should pass with "Response: Some Event"
68
+
@@ -3,6 +3,11 @@ Feature: cassette_library_dir
3
3
  The `cassette_library_dir` configuration option sets a directory
4
4
  where VCR saves each cassette.
5
5
 
6
+ Note: When using Rails, avoid using the `test/fixtures` directory
7
+ to store the cassettes. Rails treats any YAML file in the fixtures
8
+ directory as an ActiveRecord fixture.
9
+ This will cause an `ActiveRecord::Fixture::FormatError` to be raised.
10
+
6
11
  Scenario: cassette_library_dir
7
12
  Given a file named "cassette_library_dir.rb" with:
8
13
  """ruby
@@ -81,6 +81,11 @@ Feature: Preserve Exact Body Bytes
81
81
  c.cassette_library_dir = 'cassettes'
82
82
  c.hook_into :webmock
83
83
  c.default_cassette_options = { :serialize_with => :json }
84
+
85
+ c.before_record do |i|
86
+ # otherwise Ruby 2.0 will default to UTF-8:
87
+ i.response.body.force_encoding('US-ASCII')
88
+ end
84
89
  end
85
90
 
86
91
  VCR.use_cassette('preserve_bytes', :preserve_exact_body_bytes => true) do
@@ -59,9 +59,8 @@ Feature: uri_parser
59
59
  c.cassette_library_dir = 'cassettes'
60
60
  end
61
61
 
62
- uri = Addressable::URI.parse('http://bad_url.example.com')
63
62
  VCR.use_cassette('example') do
64
- puts Net::HTTP.get_response(uri).body
63
+ puts Net::HTTP.get_response('bad_url.example.com', '/').body
65
64
  end
66
65
  """
67
66
  When I run `ruby uri_parser.rb`
@@ -78,9 +77,8 @@ Feature: uri_parser
78
77
  c.cassette_library_dir = 'cassettes'
79
78
  end
80
79
 
81
- uri = Addressable::URI.parse('http://bad_url.example.com')
82
80
  VCR.use_cassette('example') do
83
- puts Net::HTTP.get_response(uri).body
81
+ puts Net::HTTP.get_response('bad_url.example.com', '/').body
84
82
  end
85
83
  """
86
84
  When I run `ruby uri_parser_default.rb`
@@ -144,7 +144,7 @@ Feature: Net::HTTP
144
144
  c.cassette_library_dir = 'cassettes'
145
145
  end
146
146
 
147
- uri = URI("https://raw.github.com/gist/fb555cb593f3349d53af/6921dd638337d3f6a51b0e02e7f30e3c414f70d6/vcr_gist")
147
+ uri = URI("https://gist.github.com/myronmarston/fb555cb593f3349d53af/raw/6921dd638337d3f6a51b0e02e7f30e3c414f70d6/vcr_gist")
148
148
 
149
149
  VCR.use_cassette('https') do
150
150
  http = Net::HTTP.new(uri.host, uri.port)
@@ -83,5 +83,4 @@ Feature: Matching on Headers
83
83
  | c.hook_into :webmock | curb |
84
84
  | c.hook_into :webmock | patron |
85
85
  | c.hook_into :webmock | em-http-request |
86
- | c.hook_into :excon | excon |
87
86
 
@@ -31,6 +31,7 @@ module VCRHelpers
31
31
  i.request.body ||= ''
32
32
  i.response.body ||= ''
33
33
  i.response.status.message ||= ''
34
+ i.response.adapter_metadata.clear
34
35
 
35
36
  # Remove non-deterministic headers and headers
36
37
  # that get added by a particular HTTP library (but not by others)
@@ -168,10 +169,6 @@ Then /^the file "([^"]*)" should contain each of these:$/ do |file_name, table|
168
169
  end
169
170
  end
170
171
 
171
- Then /^the file "([^"]*)" should contain:$/ do |file_name, expected_content|
172
- check_file_content(file_name, expected_content, true)
173
- end
174
-
175
172
  Then /^the file "([^"]*)" should contain a YAML fragment like:$/ do |file_name, fragment|
176
173
  in_current_dir do
177
174
  file_content = File.read(file_name)
@@ -149,3 +149,62 @@ Feature: Usage with Cucumber
149
149
  And the file "features/cassettes/allowed.yml" should contain "Hello allowed"
150
150
  And the file "features/cassettes/VCR_example/tagged_scenario.yml" should contain "Hello localhost_request_1"
151
151
  And the file "features/cassettes/VCR_example/tagged_scenario_outline/_foo_bar_.yml" should contain "Hello localhost_request_1"
152
+
153
+ Scenario: `:allow_unused_http_interactions => false` does not raise if the scenario already failed
154
+ Given a previously recorded cassette file "features/cassettes/cucumber_tags/example.yml" with:
155
+ """
156
+ ---
157
+ http_interactions:
158
+ - request:
159
+ method: get
160
+ uri: http://example.com/foo
161
+ body:
162
+ encoding: UTF-8
163
+ string: ""
164
+ headers: {}
165
+ response:
166
+ status:
167
+ code: 200
168
+ message: OK
169
+ headers:
170
+ Content-Length:
171
+ - "5"
172
+ body:
173
+ encoding: UTF-8
174
+ string: Hello
175
+ http_version: "1.1"
176
+ recorded_at: Tue, 01 Nov 2011 04:58:44 GMT
177
+ recorded_with: VCR 2.0.0
178
+ """
179
+ And a file named "features/support/vcr.rb" with:
180
+ """ruby
181
+ require 'vcr'
182
+
183
+ VCR.configure do |c|
184
+ c.hook_into :webmock
185
+ c.cassette_library_dir = 'features/cassettes'
186
+ end
187
+
188
+ VCR.cucumber_tags do |t|
189
+ t.tag '@example', :allow_unused_http_interactions => false
190
+ end
191
+ """
192
+ And a file named "features/step_definitions/steps.rb" with:
193
+ """ruby
194
+ When /^the scenario fails$/ do
195
+ raise "boom"
196
+ end
197
+ """
198
+ And a file named "features/vcr_example.feature" with:
199
+ """
200
+ Feature:
201
+
202
+ @example
203
+ Scenario: tagged scenario
204
+ When the scenario fails
205
+ """
206
+ When I run `cucumber features/vcr_example.feature`
207
+ Then it should fail with "1 scenario (1 failed)"
208
+ And the output should contain "boom"
209
+ And the output should not contain "There are unused HTTP interactions"
210
+