vcr 3.0.3 → 6.2.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 (146) hide show
  1. checksums.yaml +5 -5
  2. data/lib/vcr/cassette/erb_renderer.rb +4 -2
  3. data/lib/vcr/cassette/http_interaction_list.rb +14 -9
  4. data/lib/vcr/cassette/migrator.rb +5 -6
  5. data/lib/vcr/cassette/persisters/file_system.rb +9 -1
  6. data/lib/vcr/cassette/serializers/compressed.rb +2 -2
  7. data/lib/vcr/cassette/serializers/json.rb +14 -8
  8. data/lib/vcr/cassette/serializers/psych.rb +10 -2
  9. data/lib/vcr/cassette/serializers/syck.rb +7 -1
  10. data/lib/vcr/cassette/serializers/yaml.rb +14 -2
  11. data/lib/vcr/cassette/serializers.rb +10 -0
  12. data/lib/vcr/cassette.rb +63 -16
  13. data/lib/vcr/configuration.rb +21 -8
  14. data/lib/vcr/deprecations.rb +0 -62
  15. data/lib/vcr/errors.rb +17 -12
  16. data/lib/vcr/library_hooks/excon.rb +8 -0
  17. data/lib/vcr/library_hooks/typhoeus.rb +91 -79
  18. data/lib/vcr/library_hooks/webmock.rb +2 -11
  19. data/lib/vcr/linked_cassette.rb +4 -4
  20. data/lib/vcr/middleware/excon.rb +1 -1
  21. data/lib/vcr/middleware/faraday.rb +29 -2
  22. data/lib/vcr/request_ignorer.rb +8 -1
  23. data/lib/vcr/request_matcher_registry.rb +3 -3
  24. data/lib/vcr/structs.rb +48 -32
  25. data/lib/vcr/test_frameworks/cucumber.rb +16 -5
  26. data/lib/vcr/test_frameworks/rspec.rb +34 -22
  27. data/lib/vcr/util/hooks.rb +1 -0
  28. data/lib/vcr/util/internet_connection.rb +15 -21
  29. data/lib/vcr/version.rb +2 -2
  30. data/lib/vcr.rb +52 -2
  31. metadata +45 -272
  32. data/features/CHANGELOG.md +0 -710
  33. data/features/CONTRIBUTING.md +0 -26
  34. data/features/LICENSE.md +0 -20
  35. data/features/README.md +0 -339
  36. data/features/Upgrade.md +0 -289
  37. data/features/about_these_examples.md +0 -18
  38. data/features/cassettes/allow_unused_http_interactions.feature +0 -100
  39. data/features/cassettes/automatic_re_recording.feature +0 -72
  40. data/features/cassettes/decompress.feature +0 -74
  41. data/features/cassettes/dynamic_erb.feature +0 -100
  42. data/features/cassettes/exclusive.feature +0 -126
  43. data/features/cassettes/format.feature +0 -411
  44. data/features/cassettes/freezing_time.feature +0 -68
  45. data/features/cassettes/naming.feature +0 -28
  46. data/features/cassettes/no_cassette.feature +0 -152
  47. data/features/cassettes/update_content_length_header.feature +0 -112
  48. data/features/configuration/allow_http_connections_when_no_cassette.feature +0 -55
  49. data/features/configuration/cassette_library_dir.feature +0 -31
  50. data/features/configuration/debug_logging.feature +0 -58
  51. data/features/configuration/default_cassette_options.feature +0 -100
  52. data/features/configuration/filter_sensitive_data.feature +0 -153
  53. data/features/configuration/hook_into.feature +0 -172
  54. data/features/configuration/ignore_request.feature +0 -192
  55. data/features/configuration/preserve_exact_body_bytes.feature +0 -108
  56. data/features/configuration/query_parser.feature +0 -84
  57. data/features/configuration/uri_parser.feature +0 -93
  58. data/features/getting_started.md +0 -82
  59. data/features/hooks/after_http_request.feature +0 -58
  60. data/features/hooks/around_http_request.feature +0 -57
  61. data/features/hooks/before_http_request.feature +0 -63
  62. data/features/hooks/before_playback.feature +0 -184
  63. data/features/hooks/before_record.feature +0 -172
  64. data/features/http_libraries/em_http_request.feature +0 -250
  65. data/features/http_libraries/net_http.feature +0 -179
  66. data/features/middleware/faraday.feature +0 -56
  67. data/features/middleware/rack.feature +0 -92
  68. data/features/record_modes/all.feature +0 -82
  69. data/features/record_modes/new_episodes.feature +0 -79
  70. data/features/record_modes/none.feature +0 -72
  71. data/features/record_modes/once.feature +0 -95
  72. data/features/request_matching/README.md +0 -30
  73. data/features/request_matching/body.feature +0 -91
  74. data/features/request_matching/body_as_json.feature +0 -90
  75. data/features/request_matching/custom_matcher.feature +0 -135
  76. data/features/request_matching/headers.feature +0 -85
  77. data/features/request_matching/host.feature +0 -95
  78. data/features/request_matching/identical_request_sequence.feature +0 -89
  79. data/features/request_matching/method.feature +0 -96
  80. data/features/request_matching/path.feature +0 -96
  81. data/features/request_matching/playback_repeats.feature +0 -98
  82. data/features/request_matching/query.feature +0 -97
  83. data/features/request_matching/uri.feature +0 -94
  84. data/features/request_matching/uri_without_param.feature +0 -101
  85. data/features/step_definitions/cli_steps.rb +0 -199
  86. data/features/support/env.rb +0 -46
  87. data/features/support/http_lib_filters.rb +0 -46
  88. data/features/test_frameworks/cucumber.feature +0 -211
  89. data/features/test_frameworks/rspec_macro.feature +0 -81
  90. data/features/test_frameworks/rspec_metadata.feature +0 -150
  91. data/features/test_frameworks/test_unit.feature +0 -49
  92. data/lib/vcr/extensions/net_http_response.rb +0 -36
  93. data/lib/vcr/library_hooks/fakeweb.rb +0 -197
  94. data/lib/vcr/library_hooks/typhoeus_0.4.rb +0 -103
  95. data/spec/acceptance/concurrency_spec.rb +0 -51
  96. data/spec/acceptance/threading_spec.rb +0 -34
  97. data/spec/fixtures/cassette_spec/1_x_cassette.yml +0 -110
  98. data/spec/fixtures/cassette_spec/empty.yml +0 -0
  99. data/spec/fixtures/cassette_spec/example.yml +0 -111
  100. data/spec/fixtures/cassette_spec/with_localhost_requests.yml +0 -111
  101. data/spec/fixtures/fake_example_responses.yml +0 -110
  102. data/spec/fixtures/match_requests_on.yml +0 -187
  103. data/spec/lib/vcr/cassette/erb_renderer_spec.rb +0 -53
  104. data/spec/lib/vcr/cassette/http_interaction_list_spec.rb +0 -295
  105. data/spec/lib/vcr/cassette/migrator_spec.rb +0 -196
  106. data/spec/lib/vcr/cassette/persisters/file_system_spec.rb +0 -75
  107. data/spec/lib/vcr/cassette/persisters_spec.rb +0 -39
  108. data/spec/lib/vcr/cassette/serializers_spec.rb +0 -182
  109. data/spec/lib/vcr/cassette_spec.rb +0 -618
  110. data/spec/lib/vcr/configuration_spec.rb +0 -326
  111. data/spec/lib/vcr/deprecations_spec.rb +0 -85
  112. data/spec/lib/vcr/errors_spec.rb +0 -178
  113. data/spec/lib/vcr/extensions/net_http_response_spec.rb +0 -86
  114. data/spec/lib/vcr/library_hooks/excon_spec.rb +0 -104
  115. data/spec/lib/vcr/library_hooks/fakeweb_spec.rb +0 -169
  116. data/spec/lib/vcr/library_hooks/faraday_spec.rb +0 -68
  117. data/spec/lib/vcr/library_hooks/typhoeus_0.4_spec.rb +0 -36
  118. data/spec/lib/vcr/library_hooks/typhoeus_spec.rb +0 -162
  119. data/spec/lib/vcr/library_hooks/webmock_spec.rb +0 -117
  120. data/spec/lib/vcr/library_hooks_spec.rb +0 -51
  121. data/spec/lib/vcr/middleware/faraday_spec.rb +0 -181
  122. data/spec/lib/vcr/middleware/rack_spec.rb +0 -115
  123. data/spec/lib/vcr/request_ignorer_spec.rb +0 -70
  124. data/spec/lib/vcr/request_matcher_registry_spec.rb +0 -345
  125. data/spec/lib/vcr/structs_spec.rb +0 -732
  126. data/spec/lib/vcr/test_frameworks/cucumber_spec.rb +0 -107
  127. data/spec/lib/vcr/test_frameworks/rspec_spec.rb +0 -94
  128. data/spec/lib/vcr/util/hooks_spec.rb +0 -158
  129. data/spec/lib/vcr/util/internet_connection_spec.rb +0 -37
  130. data/spec/lib/vcr/util/version_checker_spec.rb +0 -31
  131. data/spec/lib/vcr/version_spec.rb +0 -27
  132. data/spec/lib/vcr_spec.rb +0 -354
  133. data/spec/monkey_patches.rb +0 -186
  134. data/spec/spec_helper.rb +0 -63
  135. data/spec/support/configuration_stubbing.rb +0 -8
  136. data/spec/support/cucumber_helpers.rb +0 -39
  137. data/spec/support/fixnum_extension.rb +0 -10
  138. data/spec/support/http_library_adapters.rb +0 -289
  139. data/spec/support/limited_uri.rb +0 -21
  140. data/spec/support/ruby_interpreter.rb +0 -7
  141. data/spec/support/shared_example_groups/excon.rb +0 -63
  142. data/spec/support/shared_example_groups/hook_into_http_library.rb +0 -594
  143. data/spec/support/shared_example_groups/request_hooks.rb +0 -59
  144. data/spec/support/sinatra_app.rb +0 -86
  145. data/spec/support/vcr_localhost_server.rb +0 -76
  146. data/spec/support/vcr_stub_helpers.rb +0 -17
@@ -1,101 +0,0 @@
1
- Feature: URI without param(s)
2
-
3
- A common source of difficulty when using VCR with the default matchers
4
- are non-deterministic URIs. If the URI changes on every test run (because
5
- it includes a timestamp parameter, or whatever), the default URI matcher
6
- will not work well for you.
7
-
8
- You can write a custom matcher to match URIs however you want, but for the
9
- common need to match on a URI and ignore particular query parameters, VCR
10
- provides an easier way:
11
-
12
- :match_requests_on => [
13
- :method,
14
- VCR.request_matchers.uri_without_param(:timestamp)
15
- ]
16
-
17
- `uri_without_param` also has a plural alias (i.e. `uri_without_params(:timestamp, :session)`)
18
-
19
- Background:
20
- Given a previously recorded cassette file "cassettes/example.yml" with:
21
- """
22
- ---
23
- http_interactions:
24
- - request:
25
- method: get
26
- uri: http://example.com/search?q=foo&timestamp=1316920490
27
- body:
28
- encoding: UTF-8
29
- string: ""
30
- headers: {}
31
- response:
32
- status:
33
- code: 200
34
- message: OK
35
- headers:
36
- Content-Length:
37
- - "12"
38
- body:
39
- encoding: UTF-8
40
- string: foo response
41
- http_version: "1.1"
42
- recorded_at: Tue, 01 Nov 2011 04:58:44 GMT
43
- - request:
44
- method: get
45
- uri: http://example.com/search?q=bar&timestamp=1296723437
46
- body:
47
- encoding: UTF-8
48
- string: ""
49
- headers: {}
50
- response:
51
- status:
52
- code: 200
53
- message: OK
54
- headers:
55
- Content-Length:
56
- - "12"
57
- body:
58
- encoding: UTF-8
59
- string: bar response
60
- http_version: "1.1"
61
- recorded_at: Tue, 01 Nov 2011 04:58:44 GMT
62
- recorded_with: VCR 2.0.0
63
- """
64
-
65
- Scenario: Match the URI on all but the timestamp query parameter
66
- And a file named "uri_without_param_matcher.rb" with:
67
- """ruby
68
- include_http_adapter_for("net/http")
69
-
70
- require 'vcr'
71
-
72
- VCR.configure do |c|
73
- c.hook_into :webmock
74
- c.cassette_library_dir = 'cassettes'
75
- c.default_cassette_options = {
76
- :match_requests_on => [:method,
77
- VCR.request_matchers.uri_without_param(:timestamp)]
78
- }
79
- end
80
-
81
- def search_uri(q)
82
- "http://example.com/search?q=#{q}&timestamp=#{Time.now.to_i}"
83
- end
84
-
85
- VCR.use_cassette('example') do
86
- puts "Response for bar: " +
87
- response_body_for(:get, search_uri("bar"))
88
- end
89
-
90
- VCR.use_cassette('example') do
91
- puts "Response for foo: " +
92
- response_body_for(:get, search_uri("foo"))
93
- end
94
- """
95
- When I run `ruby uri_without_param_matcher.rb`
96
- Then it should pass with:
97
- """
98
- Response for bar: bar response
99
- Response for foo: foo response
100
- """
101
-
@@ -1,199 +0,0 @@
1
- require 'vcr'
2
- require 'multi_json'
3
-
4
- module VCRHelpers
5
-
6
- def normalize_cassette_hash(cassette_hash)
7
- cassette_hash['recorded_with'] = "VCR #{VCR.version}"
8
- cassette_hash['http_interactions'].map! { |h| normalize_http_interaction(h) }
9
- cassette_hash
10
- end
11
-
12
- def normalize_headers(object)
13
- object.headers = {} and return if object.headers.nil?
14
- object.headers = {}.tap do |hash|
15
- object.headers.each do |key, value|
16
- hash[key.downcase] = value
17
- end
18
- end
19
- end
20
-
21
- def static_timestamp
22
- @static_timestamp ||= Time.now
23
- end
24
-
25
- def normalize_http_interaction(hash)
26
- VCR::HTTPInteraction.from_hash(hash).tap do |i|
27
- normalize_headers(i.request)
28
- normalize_headers(i.response)
29
-
30
- i.recorded_at &&= static_timestamp
31
- i.request.body ||= ''
32
- i.response.body ||= ''
33
- i.response.status.message ||= ''
34
- i.response.adapter_metadata.clear
35
-
36
- # Remove non-deterministic headers and headers
37
- # that get added by a particular HTTP library (but not by others)
38
- i.response.headers.reject! { |k, v| %w[ server date connection ].include?(k) }
39
- i.request.headers.reject! { |k, v| %w[ accept user-agent connection expect date ].include?(k) }
40
-
41
- # Some HTTP libraries include an extra space ("OK " instead of "OK")
42
- i.response.status.message = i.response.status.message.strip
43
-
44
- if @scenario_parameters.to_s =~ /excon|faraday/
45
- # Excon/Faraday do not expose the status message or http version,
46
- # so we have no way to record these attributes.
47
- i.response.status.message = nil
48
- i.response.http_version = nil
49
- elsif @scenario_parameters.to_s.include?('webmock')
50
- # WebMock does not expose the HTTP version so we have no way to record it
51
- i.response.http_version = nil
52
- end
53
- end
54
- end
55
-
56
- def normalize_cassette_content(content)
57
- return content unless @scenario_parameters.to_s.include?('patron')
58
- cassette_hash = YAML.load(content)
59
- cassette_hash['http_interactions'].map! do |hash|
60
- VCR::HTTPInteraction.from_hash(hash).tap do |i|
61
- i.request.headers = (i.request.headers || {}).merge!('Expect' => [''])
62
- end.to_hash
63
- end
64
- YAML.dump(cassette_hash)
65
- end
66
-
67
- def modify_file(file_name, orig_text, new_text)
68
- in_current_dir do
69
- file = File.read(file_name)
70
- regex = /#{Regexp.escape(orig_text)}/
71
- expect(file).to match(regex)
72
-
73
- file = file.gsub(regex, new_text)
74
- File.open(file_name, 'w') { |f| f.write(file) }
75
- end
76
- end
77
- end
78
- World(VCRHelpers)
79
-
80
- Given(/the following files do not exist:/) do |files|
81
- check_file_presence(files.raw.map{|file_row| file_row[0]}, false)
82
- end
83
-
84
- Given(/^the directory "([^"]*)" does not exist$/) do |dir|
85
- check_directory_presence([dir], false)
86
- end
87
-
88
- Given(/^a previously recorded cassette file "([^"]*)" with:$/) do |file_name, content|
89
- write_file(file_name, normalize_cassette_content(content))
90
- end
91
-
92
- Given(/^it is (.*)$/) do |date_string|
93
- set_env('DATE_STRING', date_string)
94
- end
95
-
96
- Given(/^that port numbers in "([^"]*)" are normalized to "([^"]*)"$/) do |file_name, port|
97
- in_current_dir do
98
- contents = File.read(file_name)
99
- contents = contents.gsub(/:\d{2,}\//, ":#{port}/")
100
- File.open(file_name, 'w') { |f| f.write(contents) }
101
- end
102
- end
103
-
104
- When(/^I modify the file "([^"]*)" to replace "([^"]*)" with "([^"]*)"$/) do |file_name, orig_text, new_text|
105
- modify_file(file_name, orig_text, new_text)
106
- end
107
-
108
- When(/^I append to file "([^"]*)":$/) do |file_name, content|
109
- append_to_file(file_name, "\n" + content)
110
- end
111
-
112
- When(/^I set the "([^"]*)" environment variable to "([^"]*)"$/) do |var, value|
113
- set_env(var, value)
114
- end
115
-
116
- Then(/^the file "([^"]*)" should exist$/) do |file_name|
117
- check_file_presence([file_name], true)
118
- end
119
-
120
- Then(/^it should (pass|fail) with "([^"]*)"$/) do |pass_fail, partial_output|
121
- assert_exit_status_and_partial_output(pass_fail == 'pass', partial_output)
122
- end
123
-
124
- Then(/^it should (pass|fail) with an error like:$/) do |pass_fail, partial_output|
125
- assert_success(pass_fail == 'pass')
126
-
127
- # different implementations place the exception class at different
128
- # places relative to the message (i.e. with a multiline error message)
129
- process_output = all_output.gsub(/\s*\(VCR::Errors::\w+\)/, '')
130
-
131
- # Some implementations include extra leading spaces, for some reason...
132
- process_output.gsub!(/^\s*/, '')
133
- partial_output.gsub!(/^\s*/, '')
134
-
135
- assert_partial_output(partial_output, process_output)
136
- end
137
-
138
- Then(/^the output should contain each of the following:$/) do |table|
139
- table.raw.flatten.each do |string|
140
- assert_partial_output(string, all_output)
141
- end
142
- end
143
-
144
- Then(/^the file "([^"]*)" should contain YAML like:$/) do |file_name, expected_content|
145
- actual_content = in_current_dir { File.read(file_name) }
146
- expect(normalize_cassette_hash(YAML.load(actual_content))).to eq(normalize_cassette_hash(YAML.load(expected_content.to_s)))
147
- end
148
-
149
- Then(/^the file "([^"]*)" should contain JSON like:$/) do |file_name, expected_content|
150
- actual_content = in_current_dir { File.read(file_name) }
151
- actual = MultiJson.decode(actual_content)
152
- expected = MultiJson.decode(expected_content.to_s)
153
- expect(normalize_cassette_hash(actual)).to eq(normalize_cassette_hash(expected))
154
- end
155
-
156
- Then(/^the file "([^"]*)" should contain compressed YAML like:$/) do |file_name, expected_content|
157
- actual_content = in_current_dir { File.read(file_name) }
158
- unzipped_content = Zlib::Inflate.inflate(actual_content)
159
- expect(normalize_cassette_hash(YAML.load(unzipped_content))).to eq(normalize_cassette_hash(YAML.load(expected_content.to_s)))
160
- end
161
-
162
- Then(/^the file "([^"]*)" should contain ruby like:$/) do |file_name, expected_content|
163
- actual_content = in_current_dir { File.read(file_name) }
164
- actual = eval(actual_content)
165
- expected = eval(expected_content)
166
- expect(normalize_cassette_hash(actual)).to eq(normalize_cassette_hash(expected))
167
- end
168
-
169
- Then(/^the file "([^"]*)" should contain each of these:$/) do |file_name, table|
170
- table.raw.flatten.each do |string|
171
- check_file_content(file_name, string, true)
172
- end
173
- end
174
-
175
- Then(/^the file "([^"]*)" should contain a YAML fragment like:$/) do |file_name, fragment|
176
- in_current_dir do
177
- file_content = File.read(file_name)
178
-
179
- # Normalize by removing leading and trailing whitespace...
180
- file_content = file_content.split("\n").map do |line|
181
- # Different versions of psych use single vs. double quotes
182
- # And then 2.1 sometimes adds quotes...
183
- line.strip.gsub('"', "'").gsub("'", '')
184
- end.join("\n")
185
-
186
- expect(file_content).to include(fragment.gsub("'", ''))
187
- end
188
- end
189
-
190
- Then(/^the cassette "([^"]*)" should have the following response bodies:$/) do |file, table|
191
- interactions = in_current_dir { YAML.load_file(file) }['http_interactions'].map { |h| VCR::HTTPInteraction.from_hash(h) }
192
- actual_response_bodies = interactions.map { |i| i.response.body }
193
- expected_response_bodies = table.raw.flatten
194
- expect(actual_response_bodies).to match(expected_response_bodies)
195
- end
196
-
197
- Then(/^it should (pass|fail)$/) do |pass_fail|
198
- assert_success(pass_fail == 'pass')
199
- end
@@ -1,46 +0,0 @@
1
- require 'bundler'
2
- Bundler.setup
3
-
4
- ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : "ruby"
5
-
6
- require 'aruba/cucumber'
7
- require 'aruba/jruby' if RUBY_PLATFORM == 'java'
8
-
9
- gem_specs = Bundler.load.specs
10
- load_paths = Dir.glob(gem_specs.map { |spec|
11
- if spec.respond_to?(:lib_dirs_glob)
12
- spec.lib_dirs_glob
13
- else
14
- spec.load_paths
15
- end
16
- }.flatten)
17
-
18
- load_paths << File.expand_path("../../../spec", __FILE__)
19
- rubyopt = "-rsupport/cucumber_helpers"
20
-
21
- if RUBY_VERSION > '1.9'
22
- load_paths.unshift(".")
23
- rubyopt = "--disable-gems #{rubyopt}" unless "rbx" == ruby_engine
24
- end
25
-
26
- Before do
27
- @aruba_timeout_seconds = 30
28
- if "jruby" == ruby_engine
29
- @aruba_io_wait_seconds = 0.1
30
- else
31
- @aruba_io_wait_seconds = 0.02
32
- end
33
- end
34
-
35
- Before("~@with-bundler") do
36
- set_env("RUBYLIB", load_paths.join(":"))
37
- set_env("RUBYOPT", rubyopt)
38
- set_env("RBXOPT", "--disable-gems #{ENV["RBXOPT"]}") if "rbx" == ruby_engine
39
- set_env("GEM_HOME", nil)
40
- end
41
-
42
- Before("@with-bundler") do
43
- set_env("RUBYLIB", ".:#{ENV["RUBYLIB"]}:#{load_paths.last}")
44
- set_env("RUBYOPT", "#{ENV["RUBYOPT"]} -rsupport/cucumber_helpers")
45
- set_env("BUNDLE_GEMFILE", Bundler.default_gemfile.expand_path.to_s)
46
- end
@@ -1,46 +0,0 @@
1
- if RUBY_VERSION == '1.8.7'
2
- # We get timeouts on 1.8.7 w/ Patron for some reason.
3
- UNSUPPORTED_HTTP_LIBS = %w[ patron ]
4
- elsif defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
5
- # Patron is freezing up the cukes (as it does on 1.9.2)
6
-
7
- # I'm not sure why em-http-request isn't working on rbx,
8
- # but considering the fact that VCR works with all the other
9
- # libs just fine and doesn't do anything for em-http-request,
10
- # it's probably a bug in it or rbx...so ignore it, for now.
11
-
12
- # I'm getting errors in the curb C extension in rbx.
13
-
14
- # Typhoeus should be buildable on rbx, but the travis build times out,
15
- # so we skip them to speed up the build on travis.
16
- UNSUPPORTED_HTTP_LIBS = %w[ patron em-http-request curb typhoeus ]
17
- elsif RUBY_PLATFORM == 'java'
18
- # These gems have C extensions and can't install on JRuby.
19
- c_dependent_libs = %w[ typhoeus patron curb em-http-request ]
20
-
21
- # The latest version of httpclient seems to freeze up the cukes
22
- # on JRuby. I'm not sure why, and there's little benefit to running
23
- # them on JRuby...so we just skip them. Excon seems to have the same issue :(.
24
- UNSUPPORTED_HTTP_LIBS = c_dependent_libs + %w[ httpclient excon ]
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
- Before do |scenario|
32
- if scenario.respond_to?(:cell_values) && scenario.cell_values.any? { |v| v =~ UNSUPPORTED_HTTP_LIB_REGEX }
33
- scenario.skip_invoke!
34
- end
35
- end
36
- end
37
-
38
- # Set a global based on the current stubbing lib so we can put special-case
39
- # logic in our step definitions based on the http stubbing library.
40
- Before do |scenario|
41
- if scenario.respond_to?(:cell_values)
42
- @scenario_parameters = scenario.cell_values
43
- else
44
- @scenario_parameters = nil
45
- end
46
- end
@@ -1,211 +0,0 @@
1
- @with-bundler
2
- Feature: Usage with Cucumber
3
-
4
- VCR can be used with cucumber in two basic ways:
5
-
6
- - Use `VCR.use_cassette` in a step definition.
7
- - Use a `VCR.cucumber_tags` block to tell VCR to use a
8
- cassette for a tagged scenario.
9
-
10
- In a cucumber support file (e.g. features/support/vcr.rb), put code like this:
11
-
12
- ``` ruby
13
- VCR.cucumber_tags do |t|
14
- t.tag '@tag1'
15
- t.tags '@tag2', '@tag3'
16
-
17
- t.tag '@tag3', :cassette => :options
18
- t.tags '@tag4', '@tag5', :cassette => :options
19
- t.tag '@vcr', :use_scenario_name => true
20
- end
21
- ```
22
-
23
- VCR will use a cassette named `cucumber_tags/<tag_name>` for scenarios
24
- with each of these tags (Unless the `:use_scenario_name` option is provided. See below).
25
- The configured `default_cassette_options` will be used, or you can override specific
26
- options by passing a hash as the last argument to `#tag` or `#tags`.
27
-
28
- You can also have VCR name your cassettes automatically according to the feature
29
- and scenario name by providing `:use_scenario_name => true` to `#tag` or `#tags`.
30
- In this case, the cassette will be named `<feature_name>/<scenario_name>`.
31
- For scenario outlines, VCR will record one cassette per row, and the cassettes
32
- will be named `<feature_name>/<scenario_name>/<row_name>`.
33
-
34
- @exclude-jruby
35
- Scenario: Record HTTP interactions in a scenario by tagging it
36
- Given a file named "lib/server.rb" with:
37
- """ruby
38
- if ENV['WITH_SERVER'] == 'true'
39
- $server = start_sinatra_app do
40
- get('/:path') { "Hello #{params[:path]}" }
41
- end
42
- end
43
- """
44
-
45
- Given a file named "features/support/vcr.rb" with:
46
- """ruby
47
- require "lib/server"
48
- require 'vcr'
49
-
50
- VCR.configure do |c|
51
- c.hook_into :webmock
52
- c.cassette_library_dir = 'features/cassettes'
53
- c.default_cassette_options = {
54
- :match_requests_on => [:method, :host, :path]
55
- }
56
- end
57
-
58
- VCR.cucumber_tags do |t|
59
- t.tag '@localhost_request' # uses default record mode since no options are given
60
- t.tags '@disallowed_1', '@disallowed_2', :record => :none
61
- t.tag '@vcr', :use_scenario_name => true
62
- end
63
- """
64
- And a file named "features/step_definitions/steps.rb" with:
65
- """ruby
66
- require 'net/http'
67
-
68
- When /^a request is made to "([^"]*)"$/ do |url|
69
- uri = URI.parse(url)
70
- uri.port = $server.port if $server
71
- @response = Net::HTTP.get_response(uri)
72
- end
73
-
74
- When /^(.*) within a cassette named "([^"]*)"$/ do |step_name, cassette_name|
75
- VCR.use_cassette(cassette_name) { step(step_name) }
76
- end
77
-
78
- Then /^the response should be "([^"]*)"$/ do |expected_response|
79
- expect(@response.body).to eq(expected_response)
80
- end
81
- """
82
- And a file named "features/vcr_example.feature" with:
83
- """
84
- Feature: VCR example
85
-
86
- Note: Cucumber treats the pre-amble as part of the feature name. When
87
- using the :use_scenario_name option, VCR will only use the first line
88
- of the feature name as the directory for the cassette.
89
-
90
- @localhost_request
91
- Scenario: tagged scenario
92
- When a request is made to "http://localhost:7777/localhost_request_1"
93
- Then the response should be "Hello localhost_request_1"
94
- When a request is made to "http://localhost:7777/nested_cassette" within a cassette named "nested_cassette"
95
- Then the response should be "Hello nested_cassette"
96
- When a request is made to "http://localhost:7777/localhost_request_2"
97
- Then the response should be "Hello localhost_request_2"
98
-
99
- @vcr
100
- Scenario: tagged scenario
101
-
102
- Note: Like the feature pre-amble, Cucumber treats the scenario pre-amble
103
- as part of the scenario name. When using the :use_scenario_name option,
104
- VCR will only use the first line of the feature name as the directory
105
- for the cassette.
106
-
107
- When a request is made to "http://localhost:7777/localhost_request_1"
108
- Then the response should be "Hello localhost_request_1"
109
-
110
- @vcr
111
- Scenario Outline: tagged scenario outline
112
- When a request is made to "http://localhost:7777/localhost_request_1"
113
- Then the response should be "Hello localhost_request_1"
114
- Examples:
115
- | key | value |
116
- | foo | bar |
117
-
118
- @disallowed_1
119
- Scenario: tagged scenario
120
- When a request is made to "http://localhost:7777/allowed" within a cassette named "allowed"
121
- Then the response should be "Hello allowed"
122
- When a request is made to "http://localhost:7777/disallowed_1"
123
-
124
- @disallowed_2
125
- Scenario: tagged scenario
126
- When a request is made to "http://localhost:7777/disallowed_2"
127
- """
128
- And the directory "features/cassettes" does not exist
129
- When I run `cucumber WITH_SERVER=true features/vcr_example.feature`
130
- Then it should fail with "5 scenarios (2 failed, 3 passed)"
131
- And the file "features/cassettes/cucumber_tags/localhost_request.yml" should contain "Hello localhost_request_1"
132
- And the file "features/cassettes/cucumber_tags/localhost_request.yml" should contain "Hello localhost_request_2"
133
- And the file "features/cassettes/nested_cassette.yml" should contain "Hello nested_cassette"
134
- And the file "features/cassettes/allowed.yml" should contain "Hello allowed"
135
- And the file "features/cassettes/VCR_example/tagged_scenario.yml" should contain "Hello localhost_request_1"
136
- And the file "features/cassettes/VCR_example/tagged_scenario_outline/_foo_bar_.yml" should contain "Hello localhost_request_1"
137
-
138
- # Run again without the server; we'll get the same responses because VCR
139
- # will replay the recorded responses.
140
- When I run `cucumber features/vcr_example.feature`
141
- Then it should fail with "5 scenarios (2 failed, 3 passed)"
142
- And the output should contain each of the following:
143
- | An HTTP request has been made that VCR does not know how to handle: |
144
- | GET http://localhost:7777/disallowed_1 |
145
- | An HTTP request has been made that VCR does not know how to handle: |
146
- | GET http://localhost:7777/disallowed_2 |
147
- And the file "features/cassettes/cucumber_tags/localhost_request.yml" should contain "Hello localhost_request_1"
148
- And the file "features/cassettes/cucumber_tags/localhost_request.yml" should contain "Hello localhost_request_2"
149
- And the file "features/cassettes/nested_cassette.yml" should contain "Hello nested_cassette"
150
- And the file "features/cassettes/allowed.yml" should contain "Hello allowed"
151
- And the file "features/cassettes/VCR_example/tagged_scenario.yml" should contain "Hello localhost_request_1"
152
- And the file "features/cassettes/VCR_example/tagged_scenario_outline/_foo_bar_.yml" should contain "Hello localhost_request_1"
153
-
154
- Scenario: `:allow_unused_http_interactions => false` does not raise if the scenario already failed
155
- Given a previously recorded cassette file "features/cassettes/cucumber_tags/example.yml" with:
156
- """
157
- ---
158
- http_interactions:
159
- - request:
160
- method: get
161
- uri: http://example.com/foo
162
- body:
163
- encoding: UTF-8
164
- string: ""
165
- headers: {}
166
- response:
167
- status:
168
- code: 200
169
- message: OK
170
- headers:
171
- Content-Length:
172
- - "5"
173
- body:
174
- encoding: UTF-8
175
- string: Hello
176
- http_version: "1.1"
177
- recorded_at: Tue, 01 Nov 2011 04:58:44 GMT
178
- recorded_with: VCR 2.0.0
179
- """
180
- And a file named "features/support/vcr.rb" with:
181
- """ruby
182
- require 'vcr'
183
-
184
- VCR.configure do |c|
185
- c.hook_into :webmock
186
- c.cassette_library_dir = 'features/cassettes'
187
- end
188
-
189
- VCR.cucumber_tags do |t|
190
- t.tag '@example', :allow_unused_http_interactions => false
191
- end
192
- """
193
- And a file named "features/step_definitions/steps.rb" with:
194
- """ruby
195
- When /^the scenario fails$/ do
196
- raise "boom"
197
- end
198
- """
199
- And a file named "features/vcr_example.feature" with:
200
- """
201
- Feature:
202
-
203
- @example
204
- Scenario: tagged scenario
205
- When the scenario fails
206
- """
207
- When I run `cucumber features/vcr_example.feature`
208
- Then it should fail with "1 scenario (1 failed)"
209
- And the output should contain "boom"
210
- And the output should not contain "There are unused HTTP interactions"
211
-
@@ -1,81 +0,0 @@
1
- @with-bundler
2
- Feature: Usage with RSpec macro
3
-
4
- VCR provides a macro that makes it easy to use a VCR cassette for an RSpec
5
- example group. To use it, simply add `config.extend VCR::RSpec::Macros`
6
- to your RSpec configuration block.
7
-
8
- In any example group, add a `use_vcr_cassette` declaration to use a cassette
9
- for that example group. You can use this in a few different ways:
10
-
11
- - `use_vcr_cassette`
12
- - Infers a cassette name from the example group description (and parent
13
- example group descriptions).
14
- - Uses the `default_cassette_options` you have configured.
15
- - `use_vcr_cassette "Cassette Name"`
16
- - Uses the given cassette name.
17
- - Uses the `default_cassette_options` you have configured.
18
- - `use_vcr_cassette :cassette => :options`
19
- - Infers a cassette name from the example group description (and parent
20
- example group descriptions).
21
- - Uses the provided cassette options (merged with the defaults).
22
- - `use_vcr_cassette "Cassette Name", :cassette => :options`
23
- - Uses the given cassette name.
24
- - Uses the provided cassette options (merged with the defaults).
25
-
26
- Background:
27
- Given the following files do not exist:
28
- | spec/cassettes/VCR-RSpec_integration/without_an_explicit_cassette_name.yml |
29
- | spec/cassettes/net_http_example.yml |
30
- And a file named "spec/sinatra_app.rb" with:
31
- """ruby
32
- $server = start_sinatra_app do
33
- get('/') { "Hello" }
34
- end
35
- """
36
- And a file named "spec/vcr_example_spec.rb" with:
37
- """ruby
38
- require 'spec_helper'
39
-
40
- describe "VCR-RSpec integration" do
41
- def make_http_request
42
- Net::HTTP.get_response('localhost', '/', $server.port).body
43
- end
44
-
45
- context "without an explicit cassette name" do
46
- use_vcr_cassette
47
-
48
- it 'records an http request' do
49
- expect(make_http_request).to eq('Hello')
50
- end
51
- end
52
-
53
- context "with an explicit cassette name" do
54
- use_vcr_cassette "net_http_example"
55
-
56
- it 'records an http request' do
57
- expect(make_http_request).to eq('Hello')
58
- end
59
- end
60
- end
61
- """
62
-
63
- Scenario: Use `use_vcr_cassette` macro with RSpec 2
64
- Given a file named "spec/spec_helper.rb" with:
65
- """ruby
66
- require 'sinatra_app'
67
- require 'vcr'
68
-
69
- VCR.configure do |c|
70
- c.cassette_library_dir = 'spec/cassettes'
71
- c.hook_into :webmock
72
- end
73
-
74
- RSpec.configure do |c|
75
- c.extend VCR::RSpec::Macros
76
- end
77
- """
78
- When I run `rspec spec/vcr_example_spec.rb`
79
- Then the output should contain "2 examples, 0 failures"
80
- And the file "spec/cassettes/VCR-RSpec_integration/without_an_explicit_cassette_name.yml" should contain "Hello"
81
- And the file "spec/cassettes/net_http_example.yml" should contain "Hello"