mustwin-vcr 2.9.3
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.
- checksums.yaml +7 -0
- data/features/about_these_examples.md +18 -0
- data/features/cassettes/allow_unused_http_interactions.feature +100 -0
- data/features/cassettes/automatic_re_recording.feature +72 -0
- data/features/cassettes/decompress.feature +74 -0
- data/features/cassettes/dynamic_erb.feature +100 -0
- data/features/cassettes/exclusive.feature +126 -0
- data/features/cassettes/format.feature +323 -0
- data/features/cassettes/freezing_time.feature +68 -0
- data/features/cassettes/naming.feature +28 -0
- data/features/cassettes/no_cassette.feature +152 -0
- data/features/cassettes/update_content_length_header.feature +112 -0
- data/features/configuration/allow_http_connections_when_no_cassette.feature +55 -0
- data/features/configuration/cassette_library_dir.feature +31 -0
- data/features/configuration/debug_logging.feature +59 -0
- data/features/configuration/default_cassette_options.feature +100 -0
- data/features/configuration/filter_sensitive_data.feature +153 -0
- data/features/configuration/hook_into.feature +172 -0
- data/features/configuration/ignore_request.feature +192 -0
- data/features/configuration/preserve_exact_body_bytes.feature +108 -0
- data/features/configuration/query_parser.feature +84 -0
- data/features/configuration/uri_parser.feature +89 -0
- data/features/getting_started.md +82 -0
- data/features/hooks/after_http_request.feature +58 -0
- data/features/hooks/around_http_request.feature +57 -0
- data/features/hooks/before_http_request.feature +63 -0
- data/features/hooks/before_playback.feature +184 -0
- data/features/hooks/before_record.feature +172 -0
- data/features/http_libraries/em_http_request.feature +250 -0
- data/features/http_libraries/net_http.feature +179 -0
- data/features/middleware/faraday.feature +56 -0
- data/features/middleware/rack.feature +92 -0
- data/features/record_modes/all.feature +82 -0
- data/features/record_modes/new_episodes.feature +79 -0
- data/features/record_modes/none.feature +72 -0
- data/features/record_modes/once.feature +95 -0
- data/features/request_matching/README.md +30 -0
- data/features/request_matching/body.feature +91 -0
- data/features/request_matching/body_as_json.feature +90 -0
- data/features/request_matching/custom_matcher.feature +135 -0
- data/features/request_matching/headers.feature +85 -0
- data/features/request_matching/host.feature +95 -0
- data/features/request_matching/identical_request_sequence.feature +89 -0
- data/features/request_matching/method.feature +96 -0
- data/features/request_matching/path.feature +96 -0
- data/features/request_matching/playback_repeats.feature +98 -0
- data/features/request_matching/query.feature +97 -0
- data/features/request_matching/uri.feature +94 -0
- data/features/request_matching/uri_without_param.feature +101 -0
- data/features/step_definitions/cli_steps.rb +193 -0
- data/features/support/env.rb +44 -0
- data/features/support/http_lib_filters.rb +53 -0
- data/features/test_frameworks/cucumber.feature +211 -0
- data/features/test_frameworks/rspec_macro.feature +81 -0
- data/features/test_frameworks/rspec_metadata.feature +150 -0
- data/features/test_frameworks/test_unit.feature +49 -0
- data/lib/vcr.rb +347 -0
- data/lib/vcr/cassette.rb +291 -0
- data/lib/vcr/cassette/erb_renderer.rb +55 -0
- data/lib/vcr/cassette/http_interaction_list.rb +108 -0
- data/lib/vcr/cassette/migrator.rb +118 -0
- data/lib/vcr/cassette/persisters.rb +42 -0
- data/lib/vcr/cassette/persisters/file_system.rb +64 -0
- data/lib/vcr/cassette/serializers.rb +57 -0
- data/lib/vcr/cassette/serializers/json.rb +48 -0
- data/lib/vcr/cassette/serializers/psych.rb +48 -0
- data/lib/vcr/cassette/serializers/syck.rb +61 -0
- data/lib/vcr/cassette/serializers/yaml.rb +50 -0
- data/lib/vcr/configuration.rb +555 -0
- data/lib/vcr/deprecations.rb +109 -0
- data/lib/vcr/errors.rb +266 -0
- data/lib/vcr/extensions/net_http_response.rb +36 -0
- data/lib/vcr/library_hooks.rb +18 -0
- data/lib/vcr/library_hooks/excon.rb +27 -0
- data/lib/vcr/library_hooks/fakeweb.rb +196 -0
- data/lib/vcr/library_hooks/faraday.rb +51 -0
- data/lib/vcr/library_hooks/typhoeus.rb +120 -0
- data/lib/vcr/library_hooks/typhoeus_0.4.rb +103 -0
- data/lib/vcr/library_hooks/webmock.rb +164 -0
- data/lib/vcr/middleware/excon.rb +221 -0
- data/lib/vcr/middleware/excon/legacy_methods.rb +33 -0
- data/lib/vcr/middleware/faraday.rb +118 -0
- data/lib/vcr/middleware/rack.rb +79 -0
- data/lib/vcr/request_handler.rb +114 -0
- data/lib/vcr/request_ignorer.rb +43 -0
- data/lib/vcr/request_matcher_registry.rb +149 -0
- data/lib/vcr/structs.rb +578 -0
- data/lib/vcr/tasks/vcr.rake +9 -0
- data/lib/vcr/test_frameworks/cucumber.rb +64 -0
- data/lib/vcr/test_frameworks/rspec.rb +47 -0
- data/lib/vcr/util/hooks.rb +61 -0
- data/lib/vcr/util/internet_connection.rb +43 -0
- data/lib/vcr/util/logger.rb +59 -0
- data/lib/vcr/util/variable_args_block_caller.rb +13 -0
- data/lib/vcr/util/version_checker.rb +48 -0
- data/lib/vcr/version.rb +34 -0
- data/spec/acceptance/threading_spec.rb +34 -0
- data/spec/fixtures/cassette_spec/1_x_cassette.yml +110 -0
- data/spec/fixtures/cassette_spec/empty.yml +0 -0
- data/spec/fixtures/cassette_spec/example.yml +111 -0
- data/spec/fixtures/cassette_spec/with_localhost_requests.yml +111 -0
- data/spec/fixtures/fake_example_responses.yml +110 -0
- data/spec/fixtures/match_requests_on.yml +187 -0
- data/spec/lib/vcr/cassette/erb_renderer_spec.rb +53 -0
- data/spec/lib/vcr/cassette/http_interaction_list_spec.rb +295 -0
- data/spec/lib/vcr/cassette/migrator_spec.rb +195 -0
- data/spec/lib/vcr/cassette/persisters/file_system_spec.rb +69 -0
- data/spec/lib/vcr/cassette/persisters_spec.rb +39 -0
- data/spec/lib/vcr/cassette/serializers_spec.rb +176 -0
- data/spec/lib/vcr/cassette_spec.rb +618 -0
- data/spec/lib/vcr/configuration_spec.rb +326 -0
- data/spec/lib/vcr/deprecations_spec.rb +85 -0
- data/spec/lib/vcr/errors_spec.rb +162 -0
- data/spec/lib/vcr/extensions/net_http_response_spec.rb +86 -0
- data/spec/lib/vcr/library_hooks/excon_spec.rb +104 -0
- data/spec/lib/vcr/library_hooks/fakeweb_spec.rb +169 -0
- data/spec/lib/vcr/library_hooks/faraday_spec.rb +68 -0
- data/spec/lib/vcr/library_hooks/typhoeus_0.4_spec.rb +36 -0
- data/spec/lib/vcr/library_hooks/typhoeus_spec.rb +162 -0
- data/spec/lib/vcr/library_hooks/webmock_spec.rb +118 -0
- data/spec/lib/vcr/library_hooks_spec.rb +51 -0
- data/spec/lib/vcr/middleware/faraday_spec.rb +182 -0
- data/spec/lib/vcr/middleware/rack_spec.rb +115 -0
- data/spec/lib/vcr/request_ignorer_spec.rb +70 -0
- data/spec/lib/vcr/request_matcher_registry_spec.rb +345 -0
- data/spec/lib/vcr/structs_spec.rb +732 -0
- data/spec/lib/vcr/test_frameworks/cucumber_spec.rb +107 -0
- data/spec/lib/vcr/test_frameworks/rspec_spec.rb +83 -0
- data/spec/lib/vcr/util/hooks_spec.rb +158 -0
- data/spec/lib/vcr/util/internet_connection_spec.rb +37 -0
- data/spec/lib/vcr/util/version_checker_spec.rb +31 -0
- data/spec/lib/vcr/version_spec.rb +27 -0
- data/spec/lib/vcr_spec.rb +349 -0
- data/spec/monkey_patches.rb +182 -0
- data/spec/spec_helper.rb +62 -0
- data/spec/support/configuration_stubbing.rb +8 -0
- data/spec/support/cucumber_helpers.rb +35 -0
- data/spec/support/fixnum_extension.rb +10 -0
- data/spec/support/http_library_adapters.rb +289 -0
- data/spec/support/limited_uri.rb +21 -0
- data/spec/support/ruby_interpreter.rb +7 -0
- data/spec/support/shared_example_groups/excon.rb +63 -0
- data/spec/support/shared_example_groups/hook_into_http_library.rb +594 -0
- data/spec/support/shared_example_groups/request_hooks.rb +59 -0
- data/spec/support/sinatra_app.rb +86 -0
- data/spec/support/vcr_localhost_server.rb +76 -0
- data/spec/support/vcr_stub_helpers.rb +17 -0
- metadata +677 -0
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
Feature: Cassette format
|
|
2
|
+
|
|
3
|
+
VCR Cassettes are files that contain all of the information
|
|
4
|
+
about the requests and corresponding responses in a
|
|
5
|
+
human-readable/editable format. A cassette contains an array
|
|
6
|
+
of HTTP interactions, each of which has the following:
|
|
7
|
+
|
|
8
|
+
- request
|
|
9
|
+
- method
|
|
10
|
+
- uri
|
|
11
|
+
- body
|
|
12
|
+
- encoding
|
|
13
|
+
- string
|
|
14
|
+
- headers
|
|
15
|
+
- response
|
|
16
|
+
- status
|
|
17
|
+
- code
|
|
18
|
+
- message
|
|
19
|
+
- headers
|
|
20
|
+
- body
|
|
21
|
+
- encoding
|
|
22
|
+
- string
|
|
23
|
+
- http version
|
|
24
|
+
|
|
25
|
+
By default, VCR uses YAML to serialize this data. You can configure
|
|
26
|
+
VCR to use a different serializer, either on a cassette-by-cassette
|
|
27
|
+
basis, or as a default for all cassettes if you use the `default_cassette_options`.
|
|
28
|
+
|
|
29
|
+
VCR supports the following serializers out of the box:
|
|
30
|
+
|
|
31
|
+
- `:yaml`--Uses ruby's standard library YAML. This may use psych or syck,
|
|
32
|
+
depending on your ruby installation.
|
|
33
|
+
- `:syck`--Uses syck (the ruby 1.8 YAML engine). This is useful when using
|
|
34
|
+
VCR on a project that must run in environments where psych is not available
|
|
35
|
+
(such as on ruby 1.8), to ensure that syck is always used.
|
|
36
|
+
- `:psych`--Uses psych (the new ruby 1.9 YAML engine). This is useful when
|
|
37
|
+
you want to ensure that psych is always used.
|
|
38
|
+
- `:json`--Uses [multi_json](https://github.com/intridea/multi_json)
|
|
39
|
+
to serialize the cassette data as JSON.
|
|
40
|
+
|
|
41
|
+
You can also register a custom serializer using:
|
|
42
|
+
|
|
43
|
+
VCR.configure do |config|
|
|
44
|
+
config.cassette_serializers[:my_custom_serializer] = my_serializer
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
Your serializer must implement the following methods:
|
|
48
|
+
|
|
49
|
+
- `file_extension`
|
|
50
|
+
- `serialize(hash)`
|
|
51
|
+
- `deserialize(string)`
|
|
52
|
+
|
|
53
|
+
Scenario Outline: Request/Response data is saved to disk as YAML by default
|
|
54
|
+
Given a file named "cassette_yaml.rb" with:
|
|
55
|
+
"""ruby
|
|
56
|
+
include_http_adapter_for("<http_lib>")
|
|
57
|
+
|
|
58
|
+
if ARGV.any?
|
|
59
|
+
$server = start_sinatra_app do
|
|
60
|
+
get('/:path') { ARGV[0] + ' ' + params[:path] }
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
require 'vcr'
|
|
65
|
+
|
|
66
|
+
VCR.configure do |c|
|
|
67
|
+
<configuration>
|
|
68
|
+
c.cassette_library_dir = 'cassettes'
|
|
69
|
+
c.before_record do |i|
|
|
70
|
+
i.request.uri.sub!(/:\d+/, ':7777')
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
VCR.use_cassette('example') do
|
|
75
|
+
make_http_request(:get, "http://localhost:#{$server.port}/foo", nil, 'Accept-Encoding' => 'identity')
|
|
76
|
+
make_http_request(:get, "http://localhost:#{$server.port}/bar", nil, 'Accept-Encoding' => 'identity')
|
|
77
|
+
end
|
|
78
|
+
"""
|
|
79
|
+
When I successfully run `ruby cassette_yaml.rb 'Hello'`
|
|
80
|
+
Then the file "cassettes/example.yml" should contain YAML like:
|
|
81
|
+
"""
|
|
82
|
+
---
|
|
83
|
+
http_interactions:
|
|
84
|
+
- request:
|
|
85
|
+
method: get
|
|
86
|
+
uri: http://localhost:7777/foo
|
|
87
|
+
body:
|
|
88
|
+
encoding: UTF-8
|
|
89
|
+
string: ""
|
|
90
|
+
headers:
|
|
91
|
+
Accept-Encoding:
|
|
92
|
+
- identity
|
|
93
|
+
response:
|
|
94
|
+
status:
|
|
95
|
+
code: 200
|
|
96
|
+
message: OK
|
|
97
|
+
headers:
|
|
98
|
+
Content-Type:
|
|
99
|
+
- text/html;charset=utf-8
|
|
100
|
+
Content-Length:
|
|
101
|
+
- "9"
|
|
102
|
+
body:
|
|
103
|
+
encoding: UTF-8
|
|
104
|
+
string: Hello foo
|
|
105
|
+
http_version: "1.1"
|
|
106
|
+
recorded_at: Tue, 01 Nov 2011 04:58:44 GMT
|
|
107
|
+
- request:
|
|
108
|
+
method: get
|
|
109
|
+
uri: http://localhost:7777/bar
|
|
110
|
+
body:
|
|
111
|
+
encoding: UTF-8
|
|
112
|
+
string: ""
|
|
113
|
+
headers:
|
|
114
|
+
Accept-Encoding:
|
|
115
|
+
- identity
|
|
116
|
+
response:
|
|
117
|
+
status:
|
|
118
|
+
code: 200
|
|
119
|
+
message: OK
|
|
120
|
+
headers:
|
|
121
|
+
Content-Type:
|
|
122
|
+
- text/html;charset=utf-8
|
|
123
|
+
Content-Length:
|
|
124
|
+
- "9"
|
|
125
|
+
body:
|
|
126
|
+
encoding: UTF-8
|
|
127
|
+
string: Hello bar
|
|
128
|
+
http_version: "1.1"
|
|
129
|
+
recorded_at: Tue, 01 Nov 2011 04:58:44 GMT
|
|
130
|
+
recorded_with: VCR 2.0.0
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
Examples:
|
|
134
|
+
| configuration | http_lib |
|
|
135
|
+
| c.hook_into :fakeweb | net/http |
|
|
136
|
+
| c.hook_into :webmock | net/http |
|
|
137
|
+
| c.hook_into :webmock | httpclient |
|
|
138
|
+
| c.hook_into :webmock | patron |
|
|
139
|
+
| c.hook_into :webmock | curb |
|
|
140
|
+
| c.hook_into :webmock | em-http-request |
|
|
141
|
+
| c.hook_into :webmock | typhoeus |
|
|
142
|
+
| c.hook_into :typhoeus | typhoeus |
|
|
143
|
+
| c.hook_into :excon | excon |
|
|
144
|
+
| c.hook_into :faraday | faraday (w/ net_http) |
|
|
145
|
+
|
|
146
|
+
Scenario: Request/Response data can be saved as JSON
|
|
147
|
+
Given a file named "cassette_json.rb" with:
|
|
148
|
+
"""ruby
|
|
149
|
+
include_http_adapter_for("net/http")
|
|
150
|
+
|
|
151
|
+
$server = start_sinatra_app do
|
|
152
|
+
get('/:path') { ARGV[0] + ' ' + params[:path] }
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
require 'vcr'
|
|
156
|
+
|
|
157
|
+
VCR.configure do |c|
|
|
158
|
+
c.hook_into :webmock
|
|
159
|
+
c.cassette_library_dir = 'cassettes'
|
|
160
|
+
c.before_record do |i|
|
|
161
|
+
i.request.uri.sub!(/:\d+/, ':7777')
|
|
162
|
+
end
|
|
163
|
+
c.default_cassette_options = {
|
|
164
|
+
:match_requests_on => [:method, :host, :path]
|
|
165
|
+
}
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
VCR.use_cassette('example', :serialize_with => :json) do
|
|
169
|
+
puts response_body_for(:get, "http://localhost:#{$server.port}/foo", nil, 'Accept-Encoding' => 'identity')
|
|
170
|
+
puts response_body_for(:get, "http://localhost:#{$server.port}/bar", nil, 'Accept-Encoding' => 'identity')
|
|
171
|
+
end
|
|
172
|
+
"""
|
|
173
|
+
When I run `ruby cassette_json.rb 'Hello'`
|
|
174
|
+
Then the file "cassettes/example.json" should contain JSON like:
|
|
175
|
+
"""json
|
|
176
|
+
{
|
|
177
|
+
"http_interactions": [
|
|
178
|
+
{
|
|
179
|
+
"response": {
|
|
180
|
+
"body": {
|
|
181
|
+
"encoding": "UTF-8",
|
|
182
|
+
"string": "Hello foo"
|
|
183
|
+
},
|
|
184
|
+
"http_version": null,
|
|
185
|
+
"status": { "code": 200, "message": "OK" },
|
|
186
|
+
"headers": {
|
|
187
|
+
"Date": [ "Thu, 27 Oct 2011 06:16:31 GMT" ],
|
|
188
|
+
"Content-Type": [ "text/html;charset=utf-8" ],
|
|
189
|
+
"Content-Length": [ "9" ],
|
|
190
|
+
"Server": [ "WEBrick/1.3.1 (Ruby/1.8.7/2011-06-30)" ],
|
|
191
|
+
"Connection": [ "Keep-Alive" ]
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
"request": {
|
|
195
|
+
"uri": "http://localhost:7777/foo",
|
|
196
|
+
"body": {
|
|
197
|
+
"encoding": "UTF-8",
|
|
198
|
+
"string": ""
|
|
199
|
+
},
|
|
200
|
+
"method": "get",
|
|
201
|
+
"headers": {
|
|
202
|
+
"Accept-Encoding": [ "identity" ]
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
"recorded_at": "Tue, 01 Nov 2011 04:58:44 GMT"
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
"response": {
|
|
209
|
+
"body": {
|
|
210
|
+
"encoding": "UTF-8",
|
|
211
|
+
"string": "Hello bar"
|
|
212
|
+
},
|
|
213
|
+
"http_version": null,
|
|
214
|
+
"status": { "code": 200, "message": "OK" },
|
|
215
|
+
"headers": {
|
|
216
|
+
"Date": [ "Thu, 27 Oct 2011 06:16:31 GMT" ],
|
|
217
|
+
"Content-Type": [ "text/html;charset=utf-8" ],
|
|
218
|
+
"Content-Length": [ "9" ],
|
|
219
|
+
"Server": [ "WEBrick/1.3.1 (Ruby/1.8.7/2011-06-30)" ],
|
|
220
|
+
"Connection": [ "Keep-Alive" ]
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
"request": {
|
|
224
|
+
"uri": "http://localhost:7777/bar",
|
|
225
|
+
"body": {
|
|
226
|
+
"encoding": "UTF-8",
|
|
227
|
+
"string": ""
|
|
228
|
+
},
|
|
229
|
+
"method": "get",
|
|
230
|
+
"headers": {
|
|
231
|
+
"Accept-Encoding": [ "identity" ]
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
"recorded_at": "Tue, 01 Nov 2011 04:58:44 GMT"
|
|
235
|
+
}
|
|
236
|
+
],
|
|
237
|
+
"recorded_with": "VCR 2.0.0"
|
|
238
|
+
}
|
|
239
|
+
"""
|
|
240
|
+
When I run `ruby cassette_json.rb`
|
|
241
|
+
Then it should pass with:
|
|
242
|
+
"""
|
|
243
|
+
Hello foo
|
|
244
|
+
Hello bar
|
|
245
|
+
"""
|
|
246
|
+
|
|
247
|
+
Scenario: Request/Response data can be saved using a custom serializer
|
|
248
|
+
Given a file named "cassette_ruby.rb" with:
|
|
249
|
+
"""ruby
|
|
250
|
+
include_http_adapter_for("net/http")
|
|
251
|
+
|
|
252
|
+
$server = start_sinatra_app do
|
|
253
|
+
get('/:path') { ARGV[0] + ' ' + params[:path] }
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
require 'vcr'
|
|
257
|
+
|
|
258
|
+
# purely for demonstration purposes; obviously, don't actually
|
|
259
|
+
# use ruby #inspect / #eval for your serialization...
|
|
260
|
+
ruby_serializer = Object.new
|
|
261
|
+
class << ruby_serializer
|
|
262
|
+
def file_extension; "ruby"; end
|
|
263
|
+
def serialize(hash); hash.inspect; end
|
|
264
|
+
def deserialize(string); eval(string); end
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
VCR.configure do |c|
|
|
268
|
+
c.hook_into :webmock
|
|
269
|
+
c.cassette_library_dir = 'cassettes'
|
|
270
|
+
c.cassette_serializers[:ruby] = ruby_serializer
|
|
271
|
+
c.before_record do |i|
|
|
272
|
+
i.request.uri.sub!(/:\d+/, ':7777')
|
|
273
|
+
end
|
|
274
|
+
c.default_cassette_options = {
|
|
275
|
+
:match_requests_on => [:method, :host, :path]
|
|
276
|
+
}
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
VCR.use_cassette('example', :serialize_with => :ruby) do
|
|
280
|
+
puts response_body_for(:get, "http://localhost:#{$server.port}/foo", nil, 'Accept-Encoding' => 'identity')
|
|
281
|
+
puts response_body_for(:get, "http://localhost:#{$server.port}/bar", nil, 'Accept-Encoding' => 'identity')
|
|
282
|
+
end
|
|
283
|
+
"""
|
|
284
|
+
When I run `ruby cassette_ruby.rb 'Hello'`
|
|
285
|
+
Then the file "cassettes/example.ruby" should contain ruby like:
|
|
286
|
+
"""
|
|
287
|
+
{"http_interactions"=>
|
|
288
|
+
[{"request"=>
|
|
289
|
+
{"method"=>"get",
|
|
290
|
+
"uri"=>"http://localhost:7777/foo",
|
|
291
|
+
"body"=>{"encoding"=>"UTF-8", "string"=>""},
|
|
292
|
+
"headers"=>{"Accept"=>["*/*"], "Accept-Encoding"=>["identity"], "User-Agent"=>["Ruby"]}},
|
|
293
|
+
"response"=>
|
|
294
|
+
{"status"=>{"code"=>200, "message"=>"OK "},
|
|
295
|
+
"headers"=>
|
|
296
|
+
{"Content-Type"=>["text/html;charset=utf-8"],
|
|
297
|
+
"Content-Length"=>["9"],
|
|
298
|
+
"Connection"=>["Keep-Alive"]},
|
|
299
|
+
"body"=>{"encoding"=>"UTF-8", "string"=>"Hello foo"},
|
|
300
|
+
"http_version"=>nil},
|
|
301
|
+
"recorded_at"=>"Tue, 01 Nov 2011 04:58:44 GMT"},
|
|
302
|
+
{"request"=>
|
|
303
|
+
{"method"=>"get",
|
|
304
|
+
"uri"=>"http://localhost:7777/bar",
|
|
305
|
+
"body"=>{"encoding"=>"UTF-8", "string"=>""},
|
|
306
|
+
"headers"=>{"Accept"=>["*/*"], "Accept-Encoding"=>["identity"], "User-Agent"=>["Ruby"]}},
|
|
307
|
+
"response"=>
|
|
308
|
+
{"status"=>{"code"=>200, "message"=>"OK "},
|
|
309
|
+
"headers"=>
|
|
310
|
+
{"Content-Type"=>["text/html;charset=utf-8"],
|
|
311
|
+
"Content-Length"=>["9"],
|
|
312
|
+
"Connection"=>["Keep-Alive"]},
|
|
313
|
+
"body"=>{"encoding"=>"UTF-8", "string"=>"Hello bar"},
|
|
314
|
+
"http_version"=>nil},
|
|
315
|
+
"recorded_at"=>"Tue, 01 Nov 2011 04:58:44 GMT"}],
|
|
316
|
+
"recorded_with"=>"VCR 2.0.0"}
|
|
317
|
+
"""
|
|
318
|
+
When I run `ruby cassette_ruby.rb`
|
|
319
|
+
Then it should pass with:
|
|
320
|
+
"""
|
|
321
|
+
Hello foo
|
|
322
|
+
Hello bar
|
|
323
|
+
"""
|
|
@@ -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
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
Feature: Naming
|
|
2
|
+
|
|
3
|
+
When inserting or using a cassette, the first argument is the cassette name.
|
|
4
|
+
You can use any string for the name. If you use the default `:file_system`
|
|
5
|
+
storage backend, VCR will sanitize the string before using it as a file name,
|
|
6
|
+
so that it is a file-system friendly file name.
|
|
7
|
+
|
|
8
|
+
Scenario: Name sanitizing
|
|
9
|
+
Given a file named "name_sanitizing.rb" with:
|
|
10
|
+
"""ruby
|
|
11
|
+
$server = start_sinatra_app do
|
|
12
|
+
get('/') { "Hello" }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
require 'vcr'
|
|
16
|
+
|
|
17
|
+
VCR.configure do |c|
|
|
18
|
+
c.cassette_library_dir = 'cassettes'
|
|
19
|
+
c.hook_into :webmock
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
VCR.use_cassette('Fee, Fi Fo Fum') do
|
|
23
|
+
Net::HTTP.get_response('localhost', '/', $server.port)
|
|
24
|
+
end
|
|
25
|
+
"""
|
|
26
|
+
And the directory "cassettes" does not exist
|
|
27
|
+
When I run `ruby name_sanitizing.rb`
|
|
28
|
+
Then the file "cassettes/Fee_Fi_Fo_Fum.yml" should contain "Hello"
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
Feature: Error for HTTP request made when no cassette is in use
|
|
2
|
+
|
|
3
|
+
VCR is designed to help you remove all HTTP dependencies from your
|
|
4
|
+
test suite. To assist with this, VCR will cause an exception to be
|
|
5
|
+
raised when an HTTP request is made while there is no cassette in
|
|
6
|
+
use. The error is helpful to pinpoint where HTTP requests are
|
|
7
|
+
made so you can use a VCR cassette at that point in your code.
|
|
8
|
+
|
|
9
|
+
If you want insight about how VCR attempted to handle the request,
|
|
10
|
+
you can use the [debug\_logger](../configuration/debug-logging)
|
|
11
|
+
configuration option to log more details.
|
|
12
|
+
|
|
13
|
+
If you want to allow an HTTP request to proceed as normal, you can
|
|
14
|
+
set the [allow\_http\_connections\_when\_no\_cassette](../configuration/allow-http-connections-when-no-cassette)
|
|
15
|
+
configuration option or you can temporarily turn VCR off:
|
|
16
|
+
|
|
17
|
+
- `VCR.turn_off!` => turn VCR off so HTTP requests are allowed.
|
|
18
|
+
Cassette insertions will trigger an error.
|
|
19
|
+
- `VCR.turn_off!(:ignore_cassettes => true)` => turn
|
|
20
|
+
VCR off and ignore cassette insertions (so that no error is raised).
|
|
21
|
+
- `VCR.turn_on!` => turn VCR back on
|
|
22
|
+
- `VCR.turned_off { ... }` => turn VCR off for the duration of the
|
|
23
|
+
provided block.
|
|
24
|
+
|
|
25
|
+
@exclude-jruby
|
|
26
|
+
Scenario Outline: Error for request when no cassette is in use
|
|
27
|
+
Given a file named "no_cassette_error.rb" with:
|
|
28
|
+
"""ruby
|
|
29
|
+
include_http_adapter_for("<http_lib>")
|
|
30
|
+
|
|
31
|
+
require 'vcr'
|
|
32
|
+
|
|
33
|
+
VCR.configure do |c|
|
|
34
|
+
<configuration>
|
|
35
|
+
c.cassette_library_dir = 'cassettes'
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
response_body_for(:get, 'http://example.com/')
|
|
39
|
+
"""
|
|
40
|
+
When I run `ruby no_cassette_error.rb`
|
|
41
|
+
Then it should fail with "An HTTP request has been made that VCR does not know how to handle"
|
|
42
|
+
|
|
43
|
+
Examples:
|
|
44
|
+
| configuration | http_lib |
|
|
45
|
+
| c.hook_into :fakeweb | net/http |
|
|
46
|
+
| c.hook_into :webmock | net/http |
|
|
47
|
+
| c.hook_into :webmock | httpclient |
|
|
48
|
+
| c.hook_into :webmock | curb |
|
|
49
|
+
| c.hook_into :webmock | patron |
|
|
50
|
+
| c.hook_into :webmock | em-http-request |
|
|
51
|
+
| c.hook_into :webmock | typhoeus |
|
|
52
|
+
| c.hook_into :typhoeus | typhoeus |
|
|
53
|
+
| c.hook_into :excon | excon |
|
|
54
|
+
| c.hook_into :faraday | faraday (w/ net_http) |
|
|
55
|
+
|
|
56
|
+
Scenario: Temporarily turn VCR off to allow HTTP requests to procede as normal
|
|
57
|
+
Given a file named "turn_off_vcr.rb" with:
|
|
58
|
+
"""ruby
|
|
59
|
+
$server = start_sinatra_app do
|
|
60
|
+
get('/') { 'Hello' }
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
require 'vcr'
|
|
64
|
+
|
|
65
|
+
VCR.configure do |c|
|
|
66
|
+
c.hook_into :webmock
|
|
67
|
+
end
|
|
68
|
+
WebMock.allow_net_connect!
|
|
69
|
+
|
|
70
|
+
def make_request(context)
|
|
71
|
+
puts context
|
|
72
|
+
puts Net::HTTP.get_response('localhost', '/', $server.port).body
|
|
73
|
+
rescue => e
|
|
74
|
+
puts "Error: #{e.class}"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
VCR.turned_off do
|
|
78
|
+
make_request "In VCR.turned_off block"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
make_request "Outside of VCR.turned_off block"
|
|
82
|
+
|
|
83
|
+
VCR.turn_off!
|
|
84
|
+
make_request "After calling VCR.turn_off!"
|
|
85
|
+
|
|
86
|
+
VCR.turn_on!
|
|
87
|
+
make_request "After calling VCR.turn_on!"
|
|
88
|
+
"""
|
|
89
|
+
When I run `ruby turn_off_vcr.rb`
|
|
90
|
+
Then the output should contain:
|
|
91
|
+
"""
|
|
92
|
+
In VCR.turned_off block
|
|
93
|
+
Hello
|
|
94
|
+
"""
|
|
95
|
+
And the output should contain:
|
|
96
|
+
"""
|
|
97
|
+
Outside of VCR.turned_off block
|
|
98
|
+
Error: VCR::Errors::UnhandledHTTPRequestError
|
|
99
|
+
"""
|
|
100
|
+
And the output should contain:
|
|
101
|
+
"""
|
|
102
|
+
After calling VCR.turn_off!
|
|
103
|
+
Hello
|
|
104
|
+
"""
|
|
105
|
+
And the output should contain:
|
|
106
|
+
"""
|
|
107
|
+
After calling VCR.turn_on!
|
|
108
|
+
Error: VCR::Errors::UnhandledHTTPRequestError
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
Scenario: Turning VCR off prevents cassettes from being inserted
|
|
112
|
+
Given a file named "turn_off_vcr_and_insert_cassette.rb" with:
|
|
113
|
+
"""ruby
|
|
114
|
+
require 'vcr'
|
|
115
|
+
|
|
116
|
+
VCR.configure do |c|
|
|
117
|
+
c.hook_into :webmock
|
|
118
|
+
end
|
|
119
|
+
WebMock.allow_net_connect!
|
|
120
|
+
|
|
121
|
+
VCR.turn_off!
|
|
122
|
+
VCR.insert_cassette('example')
|
|
123
|
+
"""
|
|
124
|
+
When I run `ruby turn_off_vcr_and_insert_cassette.rb`
|
|
125
|
+
Then it should fail with "VCR is turned off. You must turn it on before you can insert a cassette."
|
|
126
|
+
|
|
127
|
+
Scenario: Turning VCR off with `:ignore_cassettes => true` ignores cassettes
|
|
128
|
+
Given a file named "turn_off_vcr_and_insert_cassette.rb" with:
|
|
129
|
+
"""ruby
|
|
130
|
+
$server = start_sinatra_app do
|
|
131
|
+
get('/') { 'Hello' }
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
require 'vcr'
|
|
135
|
+
|
|
136
|
+
VCR.configure do |c|
|
|
137
|
+
c.cassette_library_dir = 'cassettes'
|
|
138
|
+
c.hook_into :webmock
|
|
139
|
+
end
|
|
140
|
+
WebMock.allow_net_connect!
|
|
141
|
+
|
|
142
|
+
VCR.turn_off!(:ignore_cassettes => true)
|
|
143
|
+
|
|
144
|
+
VCR.use_cassette('example') do
|
|
145
|
+
response = Net::HTTP.get_response('localhost', '/', $server.port).body
|
|
146
|
+
puts "Response: #{response}"
|
|
147
|
+
end
|
|
148
|
+
"""
|
|
149
|
+
When I run `ruby turn_off_vcr_and_insert_cassette.rb`
|
|
150
|
+
Then it should pass with "Response: Hello"
|
|
151
|
+
And the file "cassettes/example.yml" should not exist
|
|
152
|
+
|