vcr 1.3.1 → 1.3.2

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 (72) hide show
  1. data/CHANGELOG.md +14 -2
  2. data/Gemfile +3 -0
  3. data/Gemfile.lock +20 -2
  4. data/README.md +6 -1
  5. data/Rakefile +6 -44
  6. data/benchmarks/http_stubbing_libraries.rb +4 -4
  7. data/cucumber.yml +14 -0
  8. data/features/README.md +21 -0
  9. data/features/cassettes/automatic_re_recording.feature +68 -0
  10. data/features/cassettes/dynamic_erb.feature +90 -0
  11. data/features/cassettes/format.feature +81 -0
  12. data/features/cassettes/no_cassette.feature +38 -0
  13. data/features/cassettes/record_modes/all.feature +78 -0
  14. data/features/cassettes/record_modes/new_episodes.feature +71 -0
  15. data/features/cassettes/record_modes/none.feature +65 -0
  16. data/features/cassettes/request_matching.feature +379 -0
  17. data/features/configuration/cassette_library_dir.feature +28 -0
  18. data/features/configuration/default_cassette_options.feature +80 -0
  19. data/features/configuration/ignore_localhost.feature +103 -0
  20. data/features/configuration/stub_with.feature +164 -0
  21. data/features/http_libraries/net_http.feature +137 -0
  22. data/features/step_definitions/cli_steps.rb +82 -0
  23. data/features/support/aruba_workaround/aruba_patches.rb +36 -0
  24. data/features/support/aruba_workaround/background_process.rb +4 -0
  25. data/features/support/env.rb +16 -102
  26. data/features/support/http_lib_filters.rb +37 -0
  27. data/features/support/vcr_cucumber_helpers.rb +34 -0
  28. data/features/test_frameworks/cucumber.feature +109 -0
  29. data/features/test_frameworks/rspec.feature +110 -0
  30. data/features/test_frameworks/shoulda.feature +64 -0
  31. data/features/test_frameworks/test_unit.feature +46 -0
  32. data/lib/vcr/cassette.rb +1 -1
  33. data/lib/vcr/structs.rb +64 -13
  34. data/lib/vcr/version.rb +1 -1
  35. data/{FullBuildRakeFile → script/FullBuildRakeFile} +0 -0
  36. data/script/full_build +1 -0
  37. data/spec/extensions/net_http_spec.rb +1 -1
  38. data/spec/spec_helper.rb +1 -1
  39. data/spec/structs_spec.rb +47 -16
  40. data/spec/support/vcr_localhost_server.rb +11 -5
  41. data/vcr.gemspec +2 -1
  42. metadata +82 -77
  43. data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/regex_cassette.yml +0 -43
  44. data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette1.yml +0 -43
  45. data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette2.yml +0 -63
  46. data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette3.yml +0 -85
  47. data/features/fixtures/vcr_cassettes/1.9.1/erb_cassette.yml +0 -36
  48. data/features/fixtures/vcr_cassettes/1.9.1/match_requests_on.yml +0 -35
  49. data/features/fixtures/vcr_cassettes/1.9.1/nested_replay_cassette.yml +0 -32
  50. data/features/fixtures/vcr_cassettes/1.9.1/not_the_real_response.yml +0 -43
  51. data/features/fixtures/vcr_cassettes/1.9.1/record_all.yml +0 -62
  52. data/features/fixtures/vcr_cassettes/1.9.1/replay_localhost_cassette.yml +0 -32
  53. data/features/fixtures/vcr_cassettes/not_1.9.1/cucumber_tags/regex_cassette.yml +0 -43
  54. data/features/fixtures/vcr_cassettes/not_1.9.1/cucumber_tags/replay_cassette1.yml +0 -43
  55. data/features/fixtures/vcr_cassettes/not_1.9.1/cucumber_tags/replay_cassette2.yml +0 -47
  56. data/features/fixtures/vcr_cassettes/not_1.9.1/cucumber_tags/replay_cassette3.yml +0 -85
  57. data/features/fixtures/vcr_cassettes/not_1.9.1/erb_cassette.yml +0 -36
  58. data/features/fixtures/vcr_cassettes/not_1.9.1/match_requests_on.yml +0 -35
  59. data/features/fixtures/vcr_cassettes/not_1.9.1/nested_replay_cassette.yml +0 -24
  60. data/features/fixtures/vcr_cassettes/not_1.9.1/not_the_real_response.yml +0 -43
  61. data/features/fixtures/vcr_cassettes/not_1.9.1/record_all.yml +0 -61
  62. data/features/fixtures/vcr_cassettes/not_1.9.1/replay_localhost_cassette.yml +0 -32
  63. data/features/http_client.feature +0 -16
  64. data/features/net_http.feature +0 -38
  65. data/features/record_response.feature +0 -95
  66. data/features/replay_recorded_response.feature +0 -96
  67. data/features/rspec.feature +0 -100
  68. data/features/step_definitions/http_client_steps.rb +0 -7
  69. data/features/step_definitions/net_http_steps.rb +0 -49
  70. data/features/step_definitions/vcr_steps.rb +0 -252
  71. data/features/webmock.feature +0 -26
  72. data/full_build +0 -1
@@ -0,0 +1,82 @@
1
+ require 'vcr/structs'
2
+
3
+ module VCRHelpers
4
+ YAML_REGEX_FOR_1_9_1 = Regexp.union(*[
5
+ ' request',
6
+ ' method',
7
+ ' uri',
8
+ ' body',
9
+ ' headers',
10
+ ' response',
11
+ ' status',
12
+ ' code',
13
+ ' message',
14
+ ' body',
15
+ ' http_version'
16
+ ].uniq)
17
+
18
+ def normalize_cassette_yaml(content)
19
+ return content unless RUBY_VERSION == '1.9.1'
20
+
21
+ # Ruby 1.9.1 serializes YAML a bit different, so
22
+ # we deal with that difference and add leading colons here.
23
+ content = content.gsub(YAML_REGEX_FOR_1_9_1) do |match|
24
+ match.sub(/^ +/, '\0:')
25
+ end
26
+ end
27
+
28
+ def normalize_cassette_structs(content)
29
+ content = normalize_cassette_yaml(content)
30
+ structs = YAML.load(content)
31
+
32
+ # Remove non-deterministic headers
33
+ structs.each do |s|
34
+ s.response.headers.reject! { |k, v| %w[ server date ].include?(k) }
35
+ end
36
+
37
+ structs
38
+ end
39
+ end
40
+ World(VCRHelpers)
41
+
42
+ Given /the following files do not exist:/ do |files|
43
+ check_file_presence(files.raw.map{|file_row| file_row[0]}, false)
44
+ end
45
+
46
+ Given /^the directory "([^"]*)" does not exist$/ do |dir|
47
+ check_directory_presence([dir], false)
48
+ end
49
+
50
+ Then /^the file "([^"]*)" should exist$/ do |file_name|
51
+ check_file_presence([file_name], true)
52
+ end
53
+
54
+ Then /^it should (pass|fail) with "([^"]*)"$/ do |pass_fail, partial_output|
55
+ assert_exit_status_and_partial_output(pass_fail == 'pass', partial_output)
56
+ end
57
+
58
+ Then /^the output should contain each of the following:$/ do |table|
59
+ table.raw.flatten.each do |string|
60
+ assert_partial_output(string)
61
+ end
62
+ end
63
+
64
+ Then /^the file "([^"]*)" should contain YAML like:$/ do |file_name, expected_content|
65
+ actual_content = in_current_dir { File.read(file_name) }
66
+ normalize_cassette_structs(actual_content).should == normalize_cassette_structs(expected_content)
67
+ end
68
+
69
+ Given /^a previously recorded cassette file "([^"]*)" with:$/ do |file_name, content|
70
+ create_file(file_name, normalize_cassette_yaml(content))
71
+ end
72
+
73
+ Then /^the file "([^"]*)" should contain each of these:$/ do |file_name, table|
74
+ table.raw.flatten.each do |string|
75
+ check_file_content(file_name, string, true)
76
+ end
77
+ end
78
+
79
+ Given /^(\d+) days have passed since the cassette was recorded$/ do |day_count|
80
+ set_env('DAYS_PASSED', day_count)
81
+ end
82
+
@@ -0,0 +1,36 @@
1
+ # Aruba::Api#run in aruba 0.2.4 does not work w/ JRuby or Rubinius.
2
+ # This is the version from 0.2.2 before aruba relied upon
3
+ # BackgroundProcess (which is not jruby/rbx compatible).
4
+ require 'tempfile'
5
+
6
+ Aruba::Api.module_eval do
7
+ def run(cmd, fail_on_error=true)
8
+ cmd = detect_ruby(cmd)
9
+
10
+ stderr_file = Tempfile.new('cucumber')
11
+ stderr_file.close
12
+ in_current_dir do
13
+ announce_or_puts("$ cd #{Dir.pwd}") if @announce_dir
14
+ announce_or_puts("$ #{cmd}") if @announce_cmd
15
+
16
+ mode = RUBY_VERSION =~ /^1\.9/ ? {:external_encoding=>"UTF-8"} : 'r'
17
+
18
+ IO.popen("#{cmd} 2> #{stderr_file.path}", mode) do |io|
19
+ @last_stdout = io.read
20
+ announce_or_puts(@last_stdout) if @announce_stdout
21
+ end
22
+
23
+ @last_exit_status = $?.exitstatus
24
+ end
25
+ @last_stderr = IO.read(stderr_file.path)
26
+
27
+ announce_or_puts(@last_stderr) if @announce_stderr
28
+
29
+ if(@last_exit_status != 0 && fail_on_error)
30
+ fail("Exit status was #{@last_exit_status}. Output:\n#{combined_output}")
31
+ end
32
+
33
+ @last_stderr
34
+ end
35
+ end
36
+
@@ -0,0 +1,4 @@
1
+ # Don't do anything--this is just here to allow aruba to run on JRuby/rbx.
2
+ # It requires background_process, but that doesn't work on JRuby/rbx.
3
+ # So on JRuby/rbx, we add this file's dir to the load path, in order to fake out aruba
4
+ # and force it to load this file instaed.
@@ -1,116 +1,30 @@
1
- $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../spec/support')
2
-
3
- if ENV['HTTP_STUBBING_ADAPTER'].to_s == ''
4
- ENV['HTTP_STUBBING_ADAPTER'] = 'fakeweb'
5
- warn "Using FakeWeb for VCR's cucumber features since the adapter was not specified. Set HTTP_STUBBING_ADAPTER to specify."
6
- end
7
-
8
- if ENV['HTTP_LIB'].to_s == ''
9
- ENV['HTTP_LIB'] = 'net/http'
10
- warn "Using Net::HTTP for VCR's cucumber features since the HTTP library was not specified. Set HTTP_LIB to specify."
11
- end
12
-
13
- # The HTTP library must be loaded before VCR since WebMock looks for the presence of the HTTB library class constant
14
- # to decide whether or not to hook into it.
15
- require ENV['HTTP_LIB']
16
- require 'http_library_adapters'
17
- World(HTTP_LIBRARY_ADAPTERS[ENV['HTTP_LIB']])
18
-
19
- puts "\n\n---------------- Running features using #{ENV['HTTP_STUBBING_ADAPTER']} and #{ENV['HTTP_LIB']} -----------------\n"
20
-
21
- require 'vcr'
22
- require 'ruby_interpreter'
23
- require 'vcr_localhost_server'
24
- require 'fixnum_extension'
25
-
26
1
  require 'rubygems'
27
2
  require 'bundler'
28
3
  Bundler.setup
29
4
 
30
- require 'aruba'
31
- require 'timecop'
32
-
33
- begin
34
- require 'ruby-debug'
35
- Debugger.start
36
- Debugger.settings[:autoeval] = true if Debugger.respond_to?(:settings)
37
- rescue LoadError
38
- # ruby-debug wasn't available so neither can the debugging be
39
- end unless RUBY_VERSION > '1.9.1' # ruby-debug doesn't work on 1.9.2 yet
40
-
41
- # Ruby 1.9.1 has a different yaml serialization format.
42
- YAML_SERIALIZATION_VERSION = RUBY_VERSION == '1.9.1' ? '1.9.1' : 'not_1.9.1'
43
-
44
- VCR.config do |c|
45
- c.cassette_library_dir = File.join(File.dirname(__FILE__), '..', 'fixtures', 'vcr_cassettes', YAML_SERIALIZATION_VERSION)
5
+ # Current version of aruba won't run on JRuby or Rubinius due to
6
+ # dependency on background_process. We have a work around to fix this.
7
+ NEEDS_ARUBA_FIX = defined?(RUBY_ENGINE) && %w[ jruby rbx ].include?(RUBY_ENGINE)
46
8
 
47
- stubs = [ENV['HTTP_STUBBING_ADAPTER'].to_sym, :typhoeus].uniq
48
- stubs.delete(:typhoeus) if RUBY_INTERPRETER == :jruby
49
-
50
- c.stub_with *stubs
51
- end
52
-
53
- VCR.module_eval do
54
- def self.completed_cucumber_scenarios
55
- @completed_cucumber_scenarios ||= []
56
- end
9
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/aruba_workaround' if NEEDS_ARUBA_FIX
57
10
 
58
- class << self
59
- attr_accessor :current_cucumber_scenario
60
- end
61
- end
62
-
63
- After do |scenario|
64
- Timecop.return
65
- if raised_error = (@http_requests || {}).values.flatten.detect { |result| result.is_a?(Exception) && result.message !~ /VCR/ }
66
- raise raised_error
67
- end
68
- VCR.completed_cucumber_scenarios << scenario
69
- end
70
-
71
- Before do |scenario|
72
- VCR::Config.ignore_localhost = false
73
-
74
- VCR.current_cucumber_scenario = scenario
75
- temp_dir = File.join(VCR::Config.cassette_library_dir, 'temp')
76
- FileUtils.rm_rf(temp_dir) if File.exist?(temp_dir)
77
- end
11
+ require 'aruba'
12
+ require 'aruba_patches' if NEEDS_ARUBA_FIX
78
13
 
79
- %w[not_the_real_response record_all].each do |cassette|
80
- Before("@copy_#{cassette}_to_temp") do
81
- orig_file = File.join(VCR::Config.cassette_library_dir, "#{cassette}.yml")
82
- temp_file = File.join(VCR::Config.cassette_library_dir, 'temp', "#{cassette}.yml")
83
- FileUtils.mkdir_p(File.join(VCR::Config.cassette_library_dir, 'temp'))
84
- FileUtils.cp orig_file, temp_file
14
+ Before do
15
+ this_dir = File.dirname(__FILE__)
16
+ in_current_dir do
17
+ FileUtils.ln_s File.join(this_dir, 'vcr_cucumber_helpers.rb'), 'vcr_cucumber_helpers.rb'
85
18
  end
86
19
  end
87
20
 
88
- Before('@create_replay_localhost_cassette') do
89
- orig_file = File.join(VCR::Config.cassette_library_dir, 'replay_localhost_cassette.yml')
90
- temp_file = File.join(VCR::Config.cassette_library_dir, 'temp', 'replay_localhost_cassette.yml')
91
- FileUtils.mkdir_p(File.join(VCR::Config.cassette_library_dir, 'temp'))
92
-
93
- # the port varies each time, so create a temp cassette with the correct port.
94
- port = static_rack_server('localhost response').port
95
-
96
- interactions = YAML.load(File.read(orig_file))
97
- interactions.each do |i|
98
- uri = URI.parse(i.request.uri)
99
- uri.port = port
100
- i.request.uri = uri.to_s
21
+ if RUBY_VERSION > '1.9.1'
22
+ Before do
23
+ set_env('RUBYOPT', '-I.:../../lib')
101
24
  end
102
-
103
- File.open(temp_file, 'w') { |f| f.write interactions.to_yaml }
104
- end
105
-
106
- at_exit do
107
- %w(record_cassette1 record_cassette2).each do |tag|
108
- file = File.join(VCR::Config.cassette_library_dir, 'cucumber_tags', "#{tag}.yml")
109
- FileUtils.rm_rf(file) if File.exist?(file)
25
+ elsif RUBY_PLATFORM == 'java'
26
+ Before do
27
+ set_env('RUBYOPT', '-I../../lib -rubygems')
110
28
  end
111
29
  end
112
30
 
113
- VCR.cucumber_tags do |t|
114
- t.tags '@record_cassette1', '@record_cassette2', :record => :new_episodes
115
- t.tags '@replay_cassette1', '@replay_cassette2', '@replay_cassette3', '@regex_cassette', :record => :none
116
- end
@@ -0,0 +1,37 @@
1
+ # make the values of the example row cells available as an array...
2
+ Cucumber::Ast::OutlineTable::ExampleRow.class_eval do
3
+ def cell_values
4
+ @cells.map { |c| c.value }
5
+ end
6
+ end
7
+
8
+ if RUBY_VERSION == '1.9.2'
9
+ # For some reason, the local sinatra server locks up and never exits
10
+ # when using patron on 1.9.2, even though it exits fine during the specs.
11
+ UNSUPPORTED_HTTP_LIBS = %w[ patron ]
12
+ elsif defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
13
+ # Patron is freezing up the cukes (as it does on 1.9.2)
14
+
15
+ # I'm not sure why em-http-request isn't working on rbx,
16
+ # but considering the fact that VCR works with all the other
17
+ # libs just fine and doesn't do anything for em-http-request,
18
+ # it's probably a bug in it or rbx...so ignore it, for now.
19
+
20
+ # I'm getting errors in the curb C extension in rbx.
21
+ UNSUPPORTED_HTTP_LIBS = %w[ patron em-http-request curb ]
22
+ elsif RUBY_PLATFORM == 'java'
23
+ # These gems have C extensions and can't install on JRuby.
24
+ UNSUPPORTED_HTTP_LIBS = %w[ typhoeus patron curb em-http-request ]
25
+ end
26
+
27
+ if defined?(UNSUPPORTED_HTTP_LIBS)
28
+ UNSUPPORTED_HTTP_LIB_REGEX = Regexp.union(*UNSUPPORTED_HTTP_LIBS)
29
+
30
+ # Filter out example rows that use libraries that are not supported on the current ruby interpreter
31
+ Around do |scenario, block|
32
+ unless scenario.respond_to?(:cell_values) && scenario.cell_values.any? { |v| v =~ UNSUPPORTED_HTTP_LIB_REGEX }
33
+ block.call
34
+ end
35
+ end
36
+ end
37
+
@@ -0,0 +1,34 @@
1
+ # This file gets symlinked into the tmp/aruba directory before
2
+ # each scenario so that it is available to be required in them.
3
+ $LOAD_PATH.unshift '../../spec' unless $LOAD_PATH.include?('../../spec')
4
+ $LOAD_PATH.unshift '../../lib' unless $LOAD_PATH.include?('../../lib')
5
+
6
+ RUNNING_UNDER_ARUBA = File.dirname(__FILE__) == '.' || File.dirname(__FILE__) =~ /aruba/
7
+
8
+ require 'support/fixnum_extension' if RUNNING_UNDER_ARUBA
9
+
10
+ if ENV['DAYS_PASSED']
11
+ require 'timecop'
12
+ Timecop.travel(Time.now + ENV['DAYS_PASSED'].to_i.days)
13
+ end
14
+
15
+ def include_http_adapter_for(lib)
16
+ require 'support/http_library_adapters'
17
+ require lib
18
+ include HTTP_LIBRARY_ADAPTERS[lib]
19
+ end
20
+
21
+ def response_body_for(*args)
22
+ get_body_string(make_http_request(*args))
23
+ end
24
+
25
+ def start_sinatra_app(options, &block)
26
+ raise ArgumentError.new("You must pass a port") unless options[:port]
27
+
28
+ require 'sinatra'
29
+ require 'support/vcr_localhost_server'
30
+ klass = Class.new(Sinatra::Base)
31
+ klass.class_eval(&block)
32
+
33
+ VCR::LocalhostServer.new(klass.new, options[:port])
34
+ end
@@ -0,0 +1,109 @@
1
+ Feature: Usage with cucumber
2
+
3
+ VCR can be used with cucumber in two basic ways:
4
+
5
+ * Use `VCR.use_cassette` in a step definition.
6
+ * Use a `VCR.cucumber_tags` block to tell VCR to use a
7
+ cassette for a tagged scenario.
8
+
9
+ In a cucumber support file (e.g. features/support/vcr.rb), put code like this:
10
+
11
+ VCR.cucumber_tags do |t|
12
+ t.tag '@tag1'
13
+ t.tags '@tag2', '@tag3'
14
+
15
+ t.tag '@tag3', :cassette => :options
16
+ t.tags '@tag4, '@tag5', :cassette => :options
17
+ end
18
+
19
+ VCR will use a cassette named "cucumber_tags/<tag_name>" for scenarios
20
+ with each of these tags. The configured default_cassette_options will
21
+ be used, or you can override specific options by passing a hash as the
22
+ last argument to #tag or #tags.
23
+
24
+ Scenario: Record HTTP interactions in a scenario by tagging it
25
+ Given a file named "features/support/vcr.rb" with:
26
+ """
27
+ require 'vcr_cucumber_helpers.rb'
28
+
29
+ if ENV['WITH_SERVER'] == 'true'
30
+ start_sinatra_app(:port => 7777) do
31
+ get('/:path') { "Hello #{params[:path]}" }
32
+ end
33
+ end
34
+
35
+ require 'vcr'
36
+
37
+ VCR.config do |c|
38
+ c.stub_with :webmock
39
+ c.cassette_library_dir = 'features/cassettes'
40
+ c.default_cassette_options = { :record => :new_episodes }
41
+ end
42
+
43
+ VCR.cucumber_tags do |t|
44
+ t.tag '@localhost_request' # uses default record mode since no options are given
45
+ t.tags '@disallowed_1', '@disallowed_2', :record => :none
46
+ end
47
+ """
48
+ And a file named "features/step_definitions/steps.rb" with:
49
+ """
50
+ require 'net/http'
51
+
52
+ When /^a request is made to "([^"]*)"$/ do |url|
53
+ @response = Net::HTTP.get_response(URI.parse(url))
54
+ end
55
+
56
+ When /^(.*) within a cassette named "([^"]*)"$/ do |step, cassette_name|
57
+ VCR.use_cassette(cassette_name) { When step }
58
+ end
59
+
60
+ Then /^the response should be "([^"]*)"$/ do |expected_response|
61
+ @response.body.should == expected_response
62
+ end
63
+ """
64
+ And a file named "features/vcr_example.feature" with:
65
+ """
66
+ Feature: VCR example
67
+
68
+ @localhost_request
69
+ Scenario: tagged scenario
70
+ When a request is made to "http://localhost:7777/localhost_request_1"
71
+ Then the response should be "Hello localhost_request_1"
72
+ When a request is made to "http://localhost:7777/nested_cassette" within a cassette named "nested_cassette"
73
+ Then the response should be "Hello nested_cassette"
74
+ When a request is made to "http://localhost:7777/localhost_request_2"
75
+ Then the response should be "Hello localhost_request_2"
76
+
77
+ @disallowed_1
78
+ Scenario: tagged scenario
79
+ When a request is made to "http://localhost:7777/allowed" within a cassette named "allowed"
80
+ Then the response should be "Hello allowed"
81
+ When a request is made to "http://localhost:7777/disallowed_1"
82
+
83
+ @disallowed_2
84
+ Scenario: tagged scenario
85
+ When a request is made to "http://localhost:7777/disallowed_2"
86
+ """
87
+ And the directory "features/cassettes" does not exist
88
+ When I run "cucumber WITH_SERVER=true features/vcr_example.feature"
89
+ Then it should fail with "3 scenarios (2 failed, 1 passed)"
90
+ And the output should contain each of the following:
91
+ | Real HTTP connections are disabled. Unregistered request: GET http://localhost:7777/disallowed_1 |
92
+ | Real HTTP connections are disabled. Unregistered request: GET http://localhost:7777/disallowed_2 |
93
+ And the file "features/cassettes/cucumber_tags/localhost_request.yml" should contain "body: Hello localhost_request_1"
94
+ And the file "features/cassettes/cucumber_tags/localhost_request.yml" should contain "body: Hello localhost_request_2"
95
+ And the file "features/cassettes/nested_cassette.yml" should contain "body: Hello nested_cassette"
96
+ And the file "features/cassettes/allowed.yml" should contain "body: Hello allowed"
97
+
98
+ # Run again without the server; we'll get the same responses because VCR
99
+ # will replay the recorded responses.
100
+ When I run "cucumber features/vcr_example.feature"
101
+ Then it should fail with "3 scenarios (2 failed, 1 passed)"
102
+ And the output should contain each of the following:
103
+ | Real HTTP connections are disabled. Unregistered request: GET http://localhost:7777/disallowed_1 |
104
+ | Real HTTP connections are disabled. Unregistered request: GET http://localhost:7777/disallowed_2 |
105
+ And the file "features/cassettes/cucumber_tags/localhost_request.yml" should contain "body: Hello localhost_request_1"
106
+ And the file "features/cassettes/cucumber_tags/localhost_request.yml" should contain "body: Hello localhost_request_2"
107
+ And the file "features/cassettes/nested_cassette.yml" should contain "body: Hello nested_cassette"
108
+ And the file "features/cassettes/allowed.yml" should contain "body: Hello allowed"
109
+
@@ -0,0 +1,110 @@
1
+ Feature: Usage with RSpec
2
+
3
+ VCR provides a macro that makes it easy to use a VCR cassette for an RSpec
4
+ example group. To use it, simply add `config.extend VCR::RSpec::Macros`
5
+ to your RSpec configuration block.
6
+
7
+ In any example group, add a `use_vcr_cassette` declaration to use a cassette
8
+ for that example group. You can use this in a few different ways:
9
+
10
+ * use_vcr_cassette
11
+ * Infers a cassette name from the example group description (and parent
12
+ example group descriptions).
13
+ * Uses the default_cassette_options you have configured.
14
+ * use_vcr_cassette "Cassette Name"
15
+ * Uses the given cassette name.
16
+ * Uses the default_cassette_options you have configured.
17
+ * use_vcr_cassette :cassette => :options
18
+ * Infers a cassette name from the example group description (and parent
19
+ example group descriptions).
20
+ * Uses the provided cassette options (merged with the defaults).
21
+ * use_vcr_cassette "Cassette Name", :cassette => :options
22
+ * Uses the given cassette name.
23
+ * Uses the provided cassette options (merged with the defaults).
24
+
25
+ Background:
26
+ Given the following files do not exist:
27
+ | spec/cassettes/VCR-RSpec_integration/without_an_explicit_cassette_name.yml |
28
+ | spec/cassettes/net_http_example.yml |
29
+ And a file named "spec/sinatra_app.rb" with:
30
+ """
31
+ require 'vcr_cucumber_helpers'
32
+
33
+ start_sinatra_app(:port => 7777) do
34
+ get('/') { "Hello" }
35
+ end
36
+ """
37
+ And a file named "spec/vcr_example_spec.rb" with:
38
+ """
39
+ require 'spec_helper'
40
+
41
+ describe "VCR-RSpec integration" do
42
+ def make_http_request
43
+ Net::HTTP.get_response('localhost', '/', 7777).body
44
+ end
45
+
46
+ context "without an explicit cassette name" do
47
+ use_vcr_cassette
48
+
49
+ it 'records an http request' do
50
+ make_http_request.should == 'Hello'
51
+ end
52
+ end
53
+
54
+ context "with an explicit cassette name" do
55
+ use_vcr_cassette "net_http_example"
56
+
57
+ it 'records an http request' do
58
+ make_http_request.should == 'Hello'
59
+ end
60
+ end
61
+ end
62
+ """
63
+
64
+ Scenario: Use `use_vcr_cassette` macro with RSpec 2
65
+ Given a file named "spec/spec_helper.rb" with:
66
+ """
67
+ require 'sinatra_app'
68
+ require 'vcr'
69
+
70
+ VCR.config do |c|
71
+ c.cassette_library_dir = 'spec/cassettes'
72
+ c.stub_with :fakeweb
73
+ c.default_cassette_options = { :record => :new_episodes }
74
+ end
75
+
76
+ RSpec.configure do |c|
77
+ c.extend VCR::RSpec::Macros
78
+ end
79
+ """
80
+ When I run "rspec spec/vcr_example_spec.rb"
81
+ Then the output should contain "2 examples, 0 failures"
82
+ And the file "spec/cassettes/VCR-RSpec_integration/without_an_explicit_cassette_name.yml" should contain "body: Hello"
83
+ And the file "spec/cassettes/net_http_example.yml" should contain "body: Hello"
84
+
85
+ Scenario: Use `use_vcr_cassette` macro with RSpec 1
86
+ Given a file named "spec/spec_helper.rb" with:
87
+ """
88
+ require 'sinatra_app'
89
+ $LOAD_PATH.unshift(File.join(%w[ .. .. vendor rspec-1 lib ]))
90
+
91
+ require 'spec'
92
+ require 'spec/autorun'
93
+
94
+ require 'vcr'
95
+
96
+ VCR.config do |c|
97
+ c.cassette_library_dir = 'spec/cassettes'
98
+ c.stub_with :fakeweb
99
+ c.default_cassette_options = { :record => :new_episodes }
100
+ end
101
+
102
+ Spec::Runner.configure do |c|
103
+ c.extend VCR::RSpec::Macros
104
+ end
105
+ """
106
+ When I run "ruby -Ispec spec/vcr_example_spec.rb"
107
+ Then the output should contain "2 examples, 0 failures"
108
+ And the file "spec/cassettes/VCR-RSpec_integration/without_an_explicit_cassette_name.yml" should contain "body: Hello"
109
+ And the file "spec/cassettes/net_http_example.yml" should contain "body: Hello"
110
+