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,84 @@
|
|
|
1
|
+
Feature: query_parser
|
|
2
|
+
|
|
3
|
+
By default, VCR will parse query strings using `CGI.parse` from the Ruby
|
|
4
|
+
standard library. This may not be the most optimal or performant library
|
|
5
|
+
available. You can set the `query_parser` configuration option to use a
|
|
6
|
+
different parser (such as `Rack::Utils.method(:parse_query)`) to decode,
|
|
7
|
+
normalize, and/or provide a comparison object for query strings.
|
|
8
|
+
|
|
9
|
+
The configured query parser needs to expose a `.call` method that returns an
|
|
10
|
+
object which is comparable. This instance needs to implement the following
|
|
11
|
+
API:
|
|
12
|
+
|
|
13
|
+
* `#==` => boolean
|
|
14
|
+
|
|
15
|
+
Background:
|
|
16
|
+
Given a file named "cassettes/example.yml" with:
|
|
17
|
+
"""
|
|
18
|
+
---
|
|
19
|
+
http_interactions:
|
|
20
|
+
- request:
|
|
21
|
+
method: get
|
|
22
|
+
uri: http://url.example.com/?bravo=2&alpha=1
|
|
23
|
+
body:
|
|
24
|
+
encoding: UTF-8
|
|
25
|
+
string: ""
|
|
26
|
+
headers: {}
|
|
27
|
+
response:
|
|
28
|
+
status:
|
|
29
|
+
code: 200
|
|
30
|
+
message: OK
|
|
31
|
+
headers:
|
|
32
|
+
Content-Length:
|
|
33
|
+
- "5"
|
|
34
|
+
body:
|
|
35
|
+
encoding: UTF-8
|
|
36
|
+
string: Hello
|
|
37
|
+
http_version: "1.1"
|
|
38
|
+
recorded_at: Tue, 25 Sep 2012 04:58:44 GMT
|
|
39
|
+
recorded_with: VCR 2.2.5
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
Scenario: the VCR query parser gets its value from `query_parser`
|
|
43
|
+
Given a file named "query_parser.rb" with:
|
|
44
|
+
"""ruby
|
|
45
|
+
require 'vcr'
|
|
46
|
+
require 'rack'
|
|
47
|
+
|
|
48
|
+
VCR.configure do |c|
|
|
49
|
+
c.query_parser = lambda { |query| raise query.inspect }
|
|
50
|
+
c.default_cassette_options = {:match_requests_on => [:query]}
|
|
51
|
+
c.hook_into :webmock
|
|
52
|
+
c.cassette_library_dir = 'cassettes'
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
uri = URI.parse('http://other-url.example.com/?bravo=2&alpha=1')
|
|
56
|
+
VCR.use_cassette('example') do
|
|
57
|
+
puts Net::HTTP.get_response(uri).body
|
|
58
|
+
end
|
|
59
|
+
"""
|
|
60
|
+
When I run `ruby query_parser.rb`
|
|
61
|
+
Then it should fail with an error like:
|
|
62
|
+
"""
|
|
63
|
+
"alpha=1&bravo=2"
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
Scenario: the `query_parser` defaults to the standard library's `CGI.parse`
|
|
68
|
+
Given a file named "query_parser_default.rb" with:
|
|
69
|
+
"""ruby
|
|
70
|
+
require 'vcr'
|
|
71
|
+
|
|
72
|
+
VCR.configure do |c|
|
|
73
|
+
c.hook_into :webmock
|
|
74
|
+
c.default_cassette_options = {:match_requests_on => [:query]}
|
|
75
|
+
c.cassette_library_dir = 'cassettes'
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
uri = URI.parse('http://other-url.example.com/?bravo=2&alpha=1')
|
|
79
|
+
VCR.use_cassette('example') do
|
|
80
|
+
puts Net::HTTP.get_response(uri).body
|
|
81
|
+
end
|
|
82
|
+
"""
|
|
83
|
+
When I run `ruby query_parser_default.rb`
|
|
84
|
+
Then it should pass with "Hello"
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
Feature: uri_parser
|
|
2
|
+
|
|
3
|
+
By default, VCR will parse URIs using `URI` from the Ruby standard
|
|
4
|
+
library. There are some URIs seen out in the wild that `URI` cannot
|
|
5
|
+
parse properly. You can set the `uri_parser` configuration option
|
|
6
|
+
to use a different parser (such as `Addressable::URI`) to work with
|
|
7
|
+
these URIs.
|
|
8
|
+
|
|
9
|
+
The configured URI parser needs to expose a `.parse` class method
|
|
10
|
+
that returns an instance of the uri. This uri instance needs to
|
|
11
|
+
implement the following API:
|
|
12
|
+
|
|
13
|
+
* `#scheme` => a string
|
|
14
|
+
* `#host` => a string
|
|
15
|
+
* `#port` => a fixnum
|
|
16
|
+
* `#path` => a string
|
|
17
|
+
* `#query` => a string
|
|
18
|
+
* `#to_s` => a string
|
|
19
|
+
* `#port=`
|
|
20
|
+
* `#query=`
|
|
21
|
+
* `#==` => boolean
|
|
22
|
+
|
|
23
|
+
Background:
|
|
24
|
+
Given a file named "cassettes/example.yml" with:
|
|
25
|
+
"""
|
|
26
|
+
---
|
|
27
|
+
http_interactions:
|
|
28
|
+
- request:
|
|
29
|
+
method: get
|
|
30
|
+
uri: http://bad_url.example.com/
|
|
31
|
+
body:
|
|
32
|
+
encoding: UTF-8
|
|
33
|
+
string: ""
|
|
34
|
+
headers: {}
|
|
35
|
+
response:
|
|
36
|
+
status:
|
|
37
|
+
code: 200
|
|
38
|
+
message: OK
|
|
39
|
+
headers:
|
|
40
|
+
Content-Length:
|
|
41
|
+
- "5"
|
|
42
|
+
body:
|
|
43
|
+
encoding: UTF-8
|
|
44
|
+
string: Hello
|
|
45
|
+
http_version: "1.1"
|
|
46
|
+
recorded_at: Tue, 25 Sep 2012 04:58:44 GMT
|
|
47
|
+
recorded_with: VCR 2.2.5
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
Scenario: the VCR uri parser gets its value from `uri_parser`
|
|
51
|
+
Given a file named "uri_parser.rb" with:
|
|
52
|
+
"""ruby
|
|
53
|
+
require 'vcr'
|
|
54
|
+
require 'addressable/uri'
|
|
55
|
+
|
|
56
|
+
VCR.configure do |c|
|
|
57
|
+
c.uri_parser = Addressable::URI
|
|
58
|
+
c.hook_into :webmock
|
|
59
|
+
c.cassette_library_dir = 'cassettes'
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
VCR.use_cassette('example') do
|
|
63
|
+
puts Net::HTTP.get_response('bad_url.example.com', '/').body
|
|
64
|
+
end
|
|
65
|
+
"""
|
|
66
|
+
When I run `ruby uri_parser.rb`
|
|
67
|
+
Then it should pass with "Hello"
|
|
68
|
+
|
|
69
|
+
Scenario: the `uri_parser` defaults to the standard library's `URI`
|
|
70
|
+
Given a file named "uri_parser_default.rb" with:
|
|
71
|
+
"""ruby
|
|
72
|
+
require 'vcr'
|
|
73
|
+
require 'addressable/uri'
|
|
74
|
+
|
|
75
|
+
VCR.configure do |c|
|
|
76
|
+
c.hook_into :webmock
|
|
77
|
+
c.cassette_library_dir = 'cassettes'
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
VCR.use_cassette('example') do
|
|
81
|
+
puts Net::HTTP.get_response('bad_url.example.com', '/').body
|
|
82
|
+
end
|
|
83
|
+
"""
|
|
84
|
+
When I run `ruby uri_parser_default.rb`
|
|
85
|
+
Then it should fail with an error like:
|
|
86
|
+
"""
|
|
87
|
+
URI::InvalidURIError
|
|
88
|
+
"""
|
|
89
|
+
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
### Install it
|
|
2
|
+
|
|
3
|
+
[sudo] gem install vcr
|
|
4
|
+
[sudo] gem install webmock
|
|
5
|
+
|
|
6
|
+
### Configure it
|
|
7
|
+
|
|
8
|
+
Create a file named `vcr_setup.rb` with content like:
|
|
9
|
+
|
|
10
|
+
require 'vcr'
|
|
11
|
+
|
|
12
|
+
VCR.configure do |c|
|
|
13
|
+
c.cassette_library_dir = 'vcr_cassettes'
|
|
14
|
+
c.hook_into :webmock
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
Ensure this file is required by your test suite before any
|
|
18
|
+
of the tests are run.
|
|
19
|
+
|
|
20
|
+
### Use it
|
|
21
|
+
|
|
22
|
+
Run your tests. Any tests that make HTTP requests using Net::HTTP will
|
|
23
|
+
raise errors like:
|
|
24
|
+
|
|
25
|
+
================================================================================
|
|
26
|
+
An HTTP request has been made that VCR does not know how to handle:
|
|
27
|
+
GET http://example.com/
|
|
28
|
+
|
|
29
|
+
There is currently no cassette in use. There are a few ways
|
|
30
|
+
you can configure VCR to handle this request:
|
|
31
|
+
|
|
32
|
+
* If you want VCR to record this request and play it back during future test
|
|
33
|
+
runs, you should wrap your test (or this portion of your test) in a
|
|
34
|
+
`VCR.use_cassette` block [1].
|
|
35
|
+
* If you only want VCR to handle requests made while a cassette is in use,
|
|
36
|
+
configure `allow_http_connections_when_no_cassette = true`. VCR will
|
|
37
|
+
ignore this request since it is made when there is no cassette [2].
|
|
38
|
+
* If you want VCR to ignore this request (and others like it), you can
|
|
39
|
+
set an `ignore_request` callback [3].
|
|
40
|
+
|
|
41
|
+
[1] https://www.relishapp.com/myronmarston/vcr/v/2-0-0/docs/getting-started
|
|
42
|
+
[2] https://www.relishapp.com/myronmarston/vcr/v/2-0-0/docs/configuration/allow-http-connections-when-no-cassette
|
|
43
|
+
[3] https://www.relishapp.com/myronmarston/vcr/v/2-0-0/docs/configuration/ignore-request
|
|
44
|
+
================================================================================
|
|
45
|
+
|
|
46
|
+
Find one of these tests (preferably one that uses the same HTTP method and
|
|
47
|
+
request URL every time--if not, you'll have to configure the request matcher).
|
|
48
|
+
Wrap the body of it (or at least the code that makes the HTTP request) in a
|
|
49
|
+
`VCR.use_cassette` block:
|
|
50
|
+
|
|
51
|
+
VCR.use_cassette('whatever cassette name you want') do
|
|
52
|
+
# the body of the test would go here...
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
Run this test. It will record the HTTP request to disk as a cassette (a
|
|
56
|
+
test fixture), with content like:
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
http_interactions:
|
|
60
|
+
- request:
|
|
61
|
+
method: get
|
|
62
|
+
uri: http://example.com/
|
|
63
|
+
body: ''
|
|
64
|
+
headers: {}
|
|
65
|
+
response:
|
|
66
|
+
status:
|
|
67
|
+
code: 200
|
|
68
|
+
message: OK
|
|
69
|
+
headers:
|
|
70
|
+
Content-Type:
|
|
71
|
+
- text/html;charset=utf-8
|
|
72
|
+
Content-Length:
|
|
73
|
+
- '26'
|
|
74
|
+
body: This is the response body
|
|
75
|
+
http_version: '1.1'
|
|
76
|
+
recorded_at: Tue, 01 Nov 2011 04:58:44 GMT
|
|
77
|
+
recorded_with: VCR 2.0.0
|
|
78
|
+
|
|
79
|
+
Disconnect your computer from the internet. Run the test again.
|
|
80
|
+
It should pass since VCR is automatically replaying the recorded
|
|
81
|
+
response when the request is made.
|
|
82
|
+
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
Feature: after_http_request hook
|
|
2
|
+
|
|
3
|
+
The `after_http_request` hook gets called with each request and response
|
|
4
|
+
just after a request has completed. It can be used for many things:
|
|
5
|
+
|
|
6
|
+
* globally logging requests and responses
|
|
7
|
+
* ejecting the current cassette (i.e. if you inserted it in a
|
|
8
|
+
`before_http_request` hook)
|
|
9
|
+
|
|
10
|
+
You can also pass one or more "filters" to `after_http_request`, to make
|
|
11
|
+
the hook only be called for some requests. Any object that responds to `#to_proc`
|
|
12
|
+
can be a filter. Here are some simple examples:
|
|
13
|
+
|
|
14
|
+
* `:real?` -- only real requests
|
|
15
|
+
* `:stubbed?` -- only stubbed requests
|
|
16
|
+
* `:ignored?` -- only ignored requests
|
|
17
|
+
* `:recordable?` -- only requests that are being recorded
|
|
18
|
+
* `lambda { |req| URI(req.uri).host == 'amazon.com' }` -- only requests to amazon.com.
|
|
19
|
+
|
|
20
|
+
Scenario Outline: log all requests and responses using after_http_request hook
|
|
21
|
+
Given a file named "after_http_request.rb" with:
|
|
22
|
+
"""ruby
|
|
23
|
+
include_http_adapter_for("<http_lib>")
|
|
24
|
+
|
|
25
|
+
$server = start_sinatra_app do
|
|
26
|
+
get('/foo') { "Hello World (foo)" }
|
|
27
|
+
get('/bar') { "Hello World (bar)" }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
require 'vcr'
|
|
31
|
+
|
|
32
|
+
VCR.configure do |c|
|
|
33
|
+
<configuration>
|
|
34
|
+
c.cassette_library_dir = 'cassettes'
|
|
35
|
+
c.ignore_localhost = true
|
|
36
|
+
c.after_http_request(:ignored?, lambda { |req| req.uri =~ /foo/ }) do |request, response|
|
|
37
|
+
uri = request.uri.sub(/:\d+/, ":7777")
|
|
38
|
+
puts "Response for #{request.method} #{uri}: #{response.body}"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
make_http_request(:get, "http://localhost:#{$server.port}/foo")
|
|
43
|
+
make_http_request(:get, "http://localhost:#{$server.port}/bar")
|
|
44
|
+
"""
|
|
45
|
+
When I run `ruby after_http_request.rb`
|
|
46
|
+
Then the output should contain "Response for get http://localhost:7777/foo: Hello World (foo)"
|
|
47
|
+
But the output should not contain "bar"
|
|
48
|
+
|
|
49
|
+
Examples:
|
|
50
|
+
| configuration | http_lib |
|
|
51
|
+
| c.hook_into :fakeweb | net/http |
|
|
52
|
+
| c.hook_into :webmock | net/http |
|
|
53
|
+
| c.hook_into :webmock | httpclient |
|
|
54
|
+
| c.hook_into :webmock | curb |
|
|
55
|
+
| c.hook_into :typhoeus | typhoeus |
|
|
56
|
+
| c.hook_into :excon | excon |
|
|
57
|
+
| c.hook_into :faraday | faraday (w/ net_http) |
|
|
58
|
+
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
@exclude-18 @exclude-1.9.3p327
|
|
2
|
+
Feature: around_http_request hook
|
|
3
|
+
|
|
4
|
+
The `around_http_request` hook wraps each HTTP request. It can be used
|
|
5
|
+
rather than separate `before_http_request` and `after_http_request` hooks
|
|
6
|
+
to simplify wrapping/transactional logic (such as using a VCR cassette).
|
|
7
|
+
|
|
8
|
+
In your block, call `#proceed` on the yielded request to cause it to continue.
|
|
9
|
+
Alternately, you can treat the request as a proc and pass it on to a method that
|
|
10
|
+
expects a block by prefixing it with an ampersand (`&request`).
|
|
11
|
+
|
|
12
|
+
Note that `around_http_request` will not work on Ruby 1.8. It uses a fiber
|
|
13
|
+
under the covers and thus is only available on interpreters that support fibers.
|
|
14
|
+
On 1.8, you can use separate `before_http_request` and `after_http_request` hooks.
|
|
15
|
+
|
|
16
|
+
Scenario Outline: globally handle requests using an around_http_request hook
|
|
17
|
+
Given a file named "globally_handle_requests.rb" with:
|
|
18
|
+
"""ruby
|
|
19
|
+
include_http_adapter_for("<http_lib>")
|
|
20
|
+
|
|
21
|
+
request_count = 0
|
|
22
|
+
$server = start_sinatra_app do
|
|
23
|
+
get('/') { "Response #{request_count += 1 }" }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
require 'vcr'
|
|
27
|
+
|
|
28
|
+
VCR.configure do |c|
|
|
29
|
+
<configuration>
|
|
30
|
+
c.cassette_library_dir = 'cassettes'
|
|
31
|
+
c.default_cassette_options = { :serialize_with => :syck }
|
|
32
|
+
c.around_http_request do |request|
|
|
33
|
+
VCR.use_cassette('global', :record => :new_episodes, &request)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
puts "Response for request 1: " + response_body_for(:get, "http://localhost:#{$server.port}/")
|
|
38
|
+
puts "Response for request 2: " + response_body_for(:get, "http://localhost:#{$server.port}/")
|
|
39
|
+
"""
|
|
40
|
+
When I run `ruby globally_handle_requests.rb`
|
|
41
|
+
Then it should pass with:
|
|
42
|
+
"""
|
|
43
|
+
Response for request 1: Response 1
|
|
44
|
+
Response for request 2: Response 1
|
|
45
|
+
"""
|
|
46
|
+
And the file "cassettes/global.yml" should contain "Response 1"
|
|
47
|
+
|
|
48
|
+
Examples:
|
|
49
|
+
| configuration | http_lib |
|
|
50
|
+
| c.hook_into :fakeweb | net/http |
|
|
51
|
+
| c.hook_into :webmock | net/http |
|
|
52
|
+
| c.hook_into :webmock | httpclient |
|
|
53
|
+
| c.hook_into :webmock | curb |
|
|
54
|
+
| c.hook_into :typhoeus | typhoeus |
|
|
55
|
+
| c.hook_into :excon | excon |
|
|
56
|
+
| c.hook_into :faraday | faraday (w/ net_http) |
|
|
57
|
+
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
Feature: before_http_request hook
|
|
2
|
+
|
|
3
|
+
The `before_http_request` hook gets called with each request
|
|
4
|
+
just before it proceeds. It can be used for many things:
|
|
5
|
+
|
|
6
|
+
* globally logging requests
|
|
7
|
+
* inserting a particular cassette based on the request URI host
|
|
8
|
+
* raising a timeout error
|
|
9
|
+
|
|
10
|
+
You can also pass one or more "filters" to `before_http_request`, to make
|
|
11
|
+
the hook only be called for some requests. Any object that responds to `#to_proc`
|
|
12
|
+
can be a filter. Here are some simple examples:
|
|
13
|
+
|
|
14
|
+
* `:real?` -- only real requests
|
|
15
|
+
* `:stubbed?` -- only stubbed requests
|
|
16
|
+
* `:ignored?` -- only ignored requests
|
|
17
|
+
* `:recordable?` -- only requests that are being recorded
|
|
18
|
+
* `lambda { |r| URI(r.uri).host == 'amazon.com' }` -- only requests to amazon.com.
|
|
19
|
+
|
|
20
|
+
Scenario Outline: log all requests using a before_http_request hook
|
|
21
|
+
Given a file named "before_http_request.rb" with:
|
|
22
|
+
"""ruby
|
|
23
|
+
include_http_adapter_for("<http_lib>")
|
|
24
|
+
|
|
25
|
+
if ARGV.include?('--with-server')
|
|
26
|
+
$server = start_sinatra_app do
|
|
27
|
+
get('/') { "Hello World" }
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
require 'vcr'
|
|
32
|
+
|
|
33
|
+
VCR.configure do |c|
|
|
34
|
+
<configuration>
|
|
35
|
+
c.cassette_library_dir = 'cassettes'
|
|
36
|
+
c.before_http_request(:real?) do |request|
|
|
37
|
+
File.open(ARGV.first, 'w') do |f|
|
|
38
|
+
f.write("before real request: #{request.method} #{request.uri}")
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
VCR.use_cassette('hook_example') do
|
|
44
|
+
port = $server ? $server.port : 0
|
|
45
|
+
make_http_request(:get, "http://localhost:#{port}/")
|
|
46
|
+
end
|
|
47
|
+
"""
|
|
48
|
+
When I run `ruby before_http_request.rb run1.log --with-server`
|
|
49
|
+
Given that port numbers in "run1.log" are normalized to "7777"
|
|
50
|
+
Then the file "run1.log" should contain "before real request: get http://localhost:7777/"
|
|
51
|
+
When I run `ruby before_http_request.rb run2.log`
|
|
52
|
+
Then the file "run2.log" should not exist
|
|
53
|
+
|
|
54
|
+
Examples:
|
|
55
|
+
| configuration | http_lib |
|
|
56
|
+
| c.hook_into :fakeweb | net/http |
|
|
57
|
+
| c.hook_into :webmock | net/http |
|
|
58
|
+
| c.hook_into :webmock | httpclient |
|
|
59
|
+
| c.hook_into :webmock | curb |
|
|
60
|
+
| c.hook_into :typhoeus | typhoeus |
|
|
61
|
+
| c.hook_into :excon | excon |
|
|
62
|
+
| c.hook_into :faraday | faraday (w/ net_http) |
|
|
63
|
+
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
Feature: before_playback hook
|
|
2
|
+
|
|
3
|
+
The `before_playback` hook is called before a cassette sets up its
|
|
4
|
+
stubs for playback.
|
|
5
|
+
|
|
6
|
+
Your block should accept up to 2 arguments. The first argument will be
|
|
7
|
+
the HTTP interaction that is about to be used for play back. The second
|
|
8
|
+
argument will be the current cassette.
|
|
9
|
+
|
|
10
|
+
You can also call `#ignore!` on the HTTP interaction to prevent VCR
|
|
11
|
+
from playing it back.
|
|
12
|
+
|
|
13
|
+
You can use tags to specify a cassette, otherwise your hook will apply to all cassettes. Consider this code:
|
|
14
|
+
|
|
15
|
+
VCR.configure do |c|
|
|
16
|
+
c.before_playback(:twitter) { ... } # modify the interactions somehow
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
VCR.use_cassette('cassette_1', :tag => :twitter) { ... }
|
|
20
|
+
VCR.use_cassette('cassette_2') { ... }
|
|
21
|
+
|
|
22
|
+
In this example, the hook would apply to the first cassette but not the
|
|
23
|
+
second cassette.
|
|
24
|
+
|
|
25
|
+
Background:
|
|
26
|
+
Given a previously recorded cassette file "cassettes/example.yml" with:
|
|
27
|
+
"""
|
|
28
|
+
---
|
|
29
|
+
http_interactions:
|
|
30
|
+
- request:
|
|
31
|
+
method: get
|
|
32
|
+
uri: http://localhost:7777/
|
|
33
|
+
body:
|
|
34
|
+
encoding: UTF-8
|
|
35
|
+
string: ""
|
|
36
|
+
headers: {}
|
|
37
|
+
response:
|
|
38
|
+
status:
|
|
39
|
+
code: 200
|
|
40
|
+
message: OK
|
|
41
|
+
headers:
|
|
42
|
+
Content-Type:
|
|
43
|
+
- text/html;charset=utf-8
|
|
44
|
+
Content-Length:
|
|
45
|
+
- "20"
|
|
46
|
+
body:
|
|
47
|
+
encoding: UTF-8
|
|
48
|
+
string: previously recorded response
|
|
49
|
+
http_version: "1.1"
|
|
50
|
+
recorded_at: Tue, 01 Nov 2011 04:58:44 GMT
|
|
51
|
+
recorded_with: VCR 2.0.0
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
Scenario: Modify played back response
|
|
55
|
+
Given a file named "before_playback_example.rb" with:
|
|
56
|
+
"""ruby
|
|
57
|
+
require 'vcr'
|
|
58
|
+
|
|
59
|
+
VCR.configure do |c|
|
|
60
|
+
c.hook_into :webmock
|
|
61
|
+
c.cassette_library_dir = 'cassettes'
|
|
62
|
+
|
|
63
|
+
c.before_playback do |interaction|
|
|
64
|
+
interaction.response.body = 'response from before_playback'
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
VCR.use_cassette('example') do
|
|
69
|
+
response = Net::HTTP.get_response('localhost', '/', 7777)
|
|
70
|
+
puts "Response: #{response.body}"
|
|
71
|
+
end
|
|
72
|
+
"""
|
|
73
|
+
When I run `ruby before_playback_example.rb`
|
|
74
|
+
Then it should pass with "Response: response from before_playback"
|
|
75
|
+
|
|
76
|
+
Scenario: Modify played back response based on the cassette
|
|
77
|
+
Given a file named "before_playback_example.rb" with:
|
|
78
|
+
"""ruby
|
|
79
|
+
require 'vcr'
|
|
80
|
+
|
|
81
|
+
VCR.configure do |c|
|
|
82
|
+
c.hook_into :webmock
|
|
83
|
+
c.cassette_library_dir = 'cassettes'
|
|
84
|
+
|
|
85
|
+
c.before_playback do |interaction, cassette|
|
|
86
|
+
interaction.response.body = "response for #{cassette.name} cassette"
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
VCR.use_cassette('example') do
|
|
91
|
+
response = Net::HTTP.get_response('localhost', '/', 7777)
|
|
92
|
+
puts "Response: #{response.body}"
|
|
93
|
+
end
|
|
94
|
+
"""
|
|
95
|
+
When I run `ruby before_playback_example.rb`
|
|
96
|
+
Then it should pass with "Response: response for example cassette"
|
|
97
|
+
|
|
98
|
+
Scenario: Prevent playback by ignoring interaction in before_playback hook
|
|
99
|
+
Given a file named "before_playback_ignore.rb" with:
|
|
100
|
+
"""ruby
|
|
101
|
+
$server = start_sinatra_app do
|
|
102
|
+
get('/') { "sinatra response" }
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
require 'vcr'
|
|
106
|
+
|
|
107
|
+
VCR.configure do |c|
|
|
108
|
+
c.hook_into :webmock
|
|
109
|
+
c.cassette_library_dir = 'cassettes'
|
|
110
|
+
c.before_playback { |i| i.ignore! }
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
VCR.use_cassette('localhost', :record => :new_episodes, :match_requests_on => [:method, :host, :path]) do
|
|
114
|
+
response = Net::HTTP.get_response('localhost', '/', $server.port)
|
|
115
|
+
puts "Response: #{response.body}"
|
|
116
|
+
end
|
|
117
|
+
"""
|
|
118
|
+
When I run `ruby before_playback_ignore.rb`
|
|
119
|
+
Then it should pass with "Response: sinatra response"
|
|
120
|
+
|
|
121
|
+
Scenario: Multiple hooks are run in order
|
|
122
|
+
Given a file named "multiple_hooks.rb" with:
|
|
123
|
+
"""ruby
|
|
124
|
+
require 'vcr'
|
|
125
|
+
|
|
126
|
+
VCR.configure do |c|
|
|
127
|
+
c.hook_into :webmock
|
|
128
|
+
c.cassette_library_dir = 'cassettes'
|
|
129
|
+
|
|
130
|
+
c.before_playback { puts "In before_playback hook 1" }
|
|
131
|
+
c.before_playback { puts "In before_playback hook 2" }
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
VCR.use_cassette('example', :record => :new_episodes) do
|
|
135
|
+
response = Net::HTTP.get_response('localhost', '/', 7777)
|
|
136
|
+
puts "Response: #{response.body}"
|
|
137
|
+
end
|
|
138
|
+
"""
|
|
139
|
+
When I run `ruby multiple_hooks.rb`
|
|
140
|
+
Then it should pass with:
|
|
141
|
+
"""
|
|
142
|
+
In before_playback hook 1
|
|
143
|
+
In before_playback hook 2
|
|
144
|
+
Response: previously recorded response
|
|
145
|
+
"""
|
|
146
|
+
|
|
147
|
+
Scenario: Use tagging to apply hooks to only certain cassettes
|
|
148
|
+
Given a file named "tagged_hooks.rb" with:
|
|
149
|
+
"""ruby
|
|
150
|
+
require 'vcr'
|
|
151
|
+
|
|
152
|
+
VCR.configure do |c|
|
|
153
|
+
c.hook_into :webmock
|
|
154
|
+
c.cassette_library_dir = 'cassettes'
|
|
155
|
+
|
|
156
|
+
c.before_playback(:tag_2) do |i|
|
|
157
|
+
puts "In before_playback hook for tag_2"
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
[:tag_1, :tag_2, nil].each do |tag|
|
|
162
|
+
puts
|
|
163
|
+
puts "Using tag: #{tag.inspect}"
|
|
164
|
+
|
|
165
|
+
VCR.use_cassette('example', :record => :new_episodes, :tag => tag) do
|
|
166
|
+
response = Net::HTTP.get_response('localhost', '/', 7777)
|
|
167
|
+
puts "Response: #{response.body}"
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
"""
|
|
171
|
+
When I run `ruby tagged_hooks.rb`
|
|
172
|
+
Then it should pass with:
|
|
173
|
+
"""
|
|
174
|
+
Using tag: :tag_1
|
|
175
|
+
Response: previously recorded response
|
|
176
|
+
|
|
177
|
+
Using tag: :tag_2
|
|
178
|
+
In before_playback hook for tag_2
|
|
179
|
+
Response: previously recorded response
|
|
180
|
+
|
|
181
|
+
Using tag: nil
|
|
182
|
+
Response: previously recorded response
|
|
183
|
+
"""
|
|
184
|
+
|