vcr 1.3.1 → 1.3.2

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