vcr 3.0.3 → 4.0.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.
- checksums.yaml +4 -4
- data/lib/vcr.rb +18 -1
- data/lib/vcr/cassette.rb +11 -3
- data/lib/vcr/cassette/persisters/file_system.rb +1 -1
- data/lib/vcr/configuration.rb +3 -5
- data/lib/vcr/deprecations.rb +0 -62
- data/lib/vcr/errors.rb +16 -0
- data/lib/vcr/library_hooks/typhoeus.rb +37 -8
- data/lib/vcr/middleware/faraday.rb +5 -1
- data/lib/vcr/structs.rb +1 -1
- data/lib/vcr/util/hooks.rb +1 -0
- data/lib/vcr/version.rb +1 -1
- metadata +9 -249
- data/features/CHANGELOG.md +0 -710
- data/features/CONTRIBUTING.md +0 -26
- data/features/LICENSE.md +0 -20
- data/features/README.md +0 -339
- data/features/Upgrade.md +0 -289
- data/features/about_these_examples.md +0 -18
- data/features/cassettes/allow_unused_http_interactions.feature +0 -100
- data/features/cassettes/automatic_re_recording.feature +0 -72
- data/features/cassettes/decompress.feature +0 -74
- data/features/cassettes/dynamic_erb.feature +0 -100
- data/features/cassettes/exclusive.feature +0 -126
- data/features/cassettes/format.feature +0 -411
- data/features/cassettes/freezing_time.feature +0 -68
- data/features/cassettes/naming.feature +0 -28
- data/features/cassettes/no_cassette.feature +0 -152
- data/features/cassettes/update_content_length_header.feature +0 -112
- data/features/configuration/allow_http_connections_when_no_cassette.feature +0 -55
- data/features/configuration/cassette_library_dir.feature +0 -31
- data/features/configuration/debug_logging.feature +0 -58
- data/features/configuration/default_cassette_options.feature +0 -100
- data/features/configuration/filter_sensitive_data.feature +0 -153
- data/features/configuration/hook_into.feature +0 -172
- data/features/configuration/ignore_request.feature +0 -192
- data/features/configuration/preserve_exact_body_bytes.feature +0 -108
- data/features/configuration/query_parser.feature +0 -84
- data/features/configuration/uri_parser.feature +0 -93
- data/features/getting_started.md +0 -82
- data/features/hooks/after_http_request.feature +0 -58
- data/features/hooks/around_http_request.feature +0 -57
- data/features/hooks/before_http_request.feature +0 -63
- data/features/hooks/before_playback.feature +0 -184
- data/features/hooks/before_record.feature +0 -172
- data/features/http_libraries/em_http_request.feature +0 -250
- data/features/http_libraries/net_http.feature +0 -179
- data/features/middleware/faraday.feature +0 -56
- data/features/middleware/rack.feature +0 -92
- data/features/record_modes/all.feature +0 -82
- data/features/record_modes/new_episodes.feature +0 -79
- data/features/record_modes/none.feature +0 -72
- data/features/record_modes/once.feature +0 -95
- data/features/request_matching/README.md +0 -30
- data/features/request_matching/body.feature +0 -91
- data/features/request_matching/body_as_json.feature +0 -90
- data/features/request_matching/custom_matcher.feature +0 -135
- data/features/request_matching/headers.feature +0 -85
- data/features/request_matching/host.feature +0 -95
- data/features/request_matching/identical_request_sequence.feature +0 -89
- data/features/request_matching/method.feature +0 -96
- data/features/request_matching/path.feature +0 -96
- data/features/request_matching/playback_repeats.feature +0 -98
- data/features/request_matching/query.feature +0 -97
- data/features/request_matching/uri.feature +0 -94
- data/features/request_matching/uri_without_param.feature +0 -101
- data/features/step_definitions/cli_steps.rb +0 -199
- data/features/support/env.rb +0 -46
- data/features/support/http_lib_filters.rb +0 -46
- data/features/test_frameworks/cucumber.feature +0 -211
- data/features/test_frameworks/rspec_macro.feature +0 -81
- data/features/test_frameworks/rspec_metadata.feature +0 -150
- data/features/test_frameworks/test_unit.feature +0 -49
- data/lib/vcr/extensions/net_http_response.rb +0 -36
- data/lib/vcr/library_hooks/fakeweb.rb +0 -197
- data/spec/acceptance/concurrency_spec.rb +0 -51
- data/spec/acceptance/threading_spec.rb +0 -34
- data/spec/fixtures/cassette_spec/1_x_cassette.yml +0 -110
- data/spec/fixtures/cassette_spec/empty.yml +0 -0
- data/spec/fixtures/cassette_spec/example.yml +0 -111
- data/spec/fixtures/cassette_spec/with_localhost_requests.yml +0 -111
- data/spec/fixtures/fake_example_responses.yml +0 -110
- data/spec/fixtures/match_requests_on.yml +0 -187
- data/spec/lib/vcr/cassette/erb_renderer_spec.rb +0 -53
- data/spec/lib/vcr/cassette/http_interaction_list_spec.rb +0 -295
- data/spec/lib/vcr/cassette/migrator_spec.rb +0 -196
- data/spec/lib/vcr/cassette/persisters/file_system_spec.rb +0 -75
- data/spec/lib/vcr/cassette/persisters_spec.rb +0 -39
- data/spec/lib/vcr/cassette/serializers_spec.rb +0 -182
- data/spec/lib/vcr/cassette_spec.rb +0 -618
- data/spec/lib/vcr/configuration_spec.rb +0 -326
- data/spec/lib/vcr/deprecations_spec.rb +0 -85
- data/spec/lib/vcr/errors_spec.rb +0 -178
- data/spec/lib/vcr/extensions/net_http_response_spec.rb +0 -86
- data/spec/lib/vcr/library_hooks/excon_spec.rb +0 -104
- data/spec/lib/vcr/library_hooks/fakeweb_spec.rb +0 -169
- data/spec/lib/vcr/library_hooks/faraday_spec.rb +0 -68
- data/spec/lib/vcr/library_hooks/typhoeus_0.4_spec.rb +0 -36
- data/spec/lib/vcr/library_hooks/typhoeus_spec.rb +0 -162
- data/spec/lib/vcr/library_hooks/webmock_spec.rb +0 -117
- data/spec/lib/vcr/library_hooks_spec.rb +0 -51
- data/spec/lib/vcr/middleware/faraday_spec.rb +0 -181
- data/spec/lib/vcr/middleware/rack_spec.rb +0 -115
- data/spec/lib/vcr/request_ignorer_spec.rb +0 -70
- data/spec/lib/vcr/request_matcher_registry_spec.rb +0 -345
- data/spec/lib/vcr/structs_spec.rb +0 -732
- data/spec/lib/vcr/test_frameworks/cucumber_spec.rb +0 -107
- data/spec/lib/vcr/test_frameworks/rspec_spec.rb +0 -94
- data/spec/lib/vcr/util/hooks_spec.rb +0 -158
- data/spec/lib/vcr/util/internet_connection_spec.rb +0 -37
- data/spec/lib/vcr/util/version_checker_spec.rb +0 -31
- data/spec/lib/vcr/version_spec.rb +0 -27
- data/spec/lib/vcr_spec.rb +0 -354
- data/spec/monkey_patches.rb +0 -186
- data/spec/spec_helper.rb +0 -63
- data/spec/support/configuration_stubbing.rb +0 -8
- data/spec/support/cucumber_helpers.rb +0 -39
- data/spec/support/fixnum_extension.rb +0 -10
- data/spec/support/http_library_adapters.rb +0 -289
- data/spec/support/limited_uri.rb +0 -21
- data/spec/support/ruby_interpreter.rb +0 -7
- data/spec/support/shared_example_groups/excon.rb +0 -63
- data/spec/support/shared_example_groups/hook_into_http_library.rb +0 -594
- data/spec/support/shared_example_groups/request_hooks.rb +0 -59
- data/spec/support/sinatra_app.rb +0 -86
- data/spec/support/vcr_localhost_server.rb +0 -76
- data/spec/support/vcr_stub_helpers.rb +0 -17
@@ -1,98 +0,0 @@
|
|
1
|
-
Feature: Playback repeats
|
2
|
-
|
3
|
-
By default, each response in a cassette can only be matched and played back
|
4
|
-
once while the cassette is in use (it can, of course, be re-used in multiple
|
5
|
-
tests, each of which should use the cassette separately). Note that this is
|
6
|
-
a change from the behavior in VCR 1.x. The old behavior occurred because of
|
7
|
-
how FakeWeb and WebMock behave internally and was not intended. Repeats create
|
8
|
-
less accurate tests since the real HTTP server may not necessarily return the
|
9
|
-
same response when identical requests are made in sequence.
|
10
|
-
|
11
|
-
If you want to allow playback repeats, VCR has a cassette option for this:
|
12
|
-
|
13
|
-
:allow_playback_repeats => true
|
14
|
-
|
15
|
-
@exclude-jruby
|
16
|
-
Scenario: Responses do not repeat by default
|
17
|
-
Given a previously recorded cassette file "cassettes/example.yml" with:
|
18
|
-
"""
|
19
|
-
---
|
20
|
-
http_interactions:
|
21
|
-
- request:
|
22
|
-
method: get
|
23
|
-
uri: http://example.com/foo
|
24
|
-
body:
|
25
|
-
encoding: UTF-8
|
26
|
-
string: ""
|
27
|
-
headers: {}
|
28
|
-
response:
|
29
|
-
status:
|
30
|
-
code: 200
|
31
|
-
message: OK
|
32
|
-
headers:
|
33
|
-
Content-Length:
|
34
|
-
- "10"
|
35
|
-
body:
|
36
|
-
encoding: UTF-8
|
37
|
-
string: Response 1
|
38
|
-
http_version: "1.1"
|
39
|
-
recorded_at: Tue, 01 Nov 2011 04:58:44 GMT
|
40
|
-
- request:
|
41
|
-
method: get
|
42
|
-
uri: http://example.com/foo
|
43
|
-
body:
|
44
|
-
encoding: UTF-8
|
45
|
-
string: ""
|
46
|
-
headers: {}
|
47
|
-
response:
|
48
|
-
status:
|
49
|
-
code: 200
|
50
|
-
message: OK
|
51
|
-
headers:
|
52
|
-
Content-Length:
|
53
|
-
- "10"
|
54
|
-
body:
|
55
|
-
encoding: UTF-8
|
56
|
-
string: Response 2
|
57
|
-
http_version: "1.1"
|
58
|
-
recorded_at: Tue, 01 Nov 2011 04:58:44 GMT
|
59
|
-
recorded_with: VCR 2.0.0
|
60
|
-
"""
|
61
|
-
And a file named "playback_repeats.rb" with:
|
62
|
-
"""ruby
|
63
|
-
include_http_adapter_for("net/http")
|
64
|
-
|
65
|
-
require 'vcr'
|
66
|
-
|
67
|
-
VCR.configure do |c|
|
68
|
-
c.hook_into :webmock
|
69
|
-
c.cassette_library_dir = 'cassettes'
|
70
|
-
end
|
71
|
-
|
72
|
-
puts "== With :allow_playback_repeats =="
|
73
|
-
VCR.use_cassette('example', :allow_playback_repeats => true) do
|
74
|
-
puts response_body_for(:get, 'http://example.com/foo')
|
75
|
-
puts response_body_for(:get, 'http://example.com/foo')
|
76
|
-
puts response_body_for(:get, 'http://example.com/foo')
|
77
|
-
end
|
78
|
-
|
79
|
-
puts "\n== Without :allow_playback_repeats =="
|
80
|
-
VCR.use_cassette('example') do
|
81
|
-
puts response_body_for(:get, 'http://example.com/foo')
|
82
|
-
puts response_body_for(:get, 'http://example.com/foo')
|
83
|
-
puts response_body_for(:get, 'http://example.com/foo')
|
84
|
-
end
|
85
|
-
"""
|
86
|
-
When I run `ruby playback_repeats.rb`
|
87
|
-
Then it should fail with "An HTTP request has been made that VCR does not know how to handle"
|
88
|
-
And the output should contain:
|
89
|
-
"""
|
90
|
-
== With :allow_playback_repeats ==
|
91
|
-
Response 1
|
92
|
-
Response 2
|
93
|
-
Response 2
|
94
|
-
|
95
|
-
== Without :allow_playback_repeats ==
|
96
|
-
Response 1
|
97
|
-
Response 2
|
98
|
-
"""
|
@@ -1,97 +0,0 @@
|
|
1
|
-
Feature: Matching on Query string
|
2
|
-
|
3
|
-
Use the `:query` request matcher to match requests on the query string
|
4
|
-
portion of the request URI.
|
5
|
-
|
6
|
-
You can use this (alone, or in combination with others) as an
|
7
|
-
alternative to `:uri` so that non-deterministic portions of the URI
|
8
|
-
are not considered as part of the request matching.
|
9
|
-
|
10
|
-
Background:
|
11
|
-
Given a previously recorded cassette file "cassettes/example.yml" with:
|
12
|
-
"""
|
13
|
-
---
|
14
|
-
http_interactions:
|
15
|
-
- request:
|
16
|
-
method: post
|
17
|
-
uri: http://host1.com/query?date=2011-09-01
|
18
|
-
body:
|
19
|
-
encoding: UTF-8
|
20
|
-
string: ""
|
21
|
-
headers: {}
|
22
|
-
response:
|
23
|
-
status:
|
24
|
-
code: 200
|
25
|
-
message: OK
|
26
|
-
headers:
|
27
|
-
Content-Length:
|
28
|
-
- "19"
|
29
|
-
body:
|
30
|
-
encoding: UTF-8
|
31
|
-
string: 2011-09-01 response
|
32
|
-
http_version: "1.1"
|
33
|
-
recorded_at: Tue, 01 Nov 2011 04:58:44 GMT
|
34
|
-
- request:
|
35
|
-
method: post
|
36
|
-
uri: http://host1.com/query?date=2011-09-02
|
37
|
-
body:
|
38
|
-
encoding: UTF-8
|
39
|
-
string: ""
|
40
|
-
headers: {}
|
41
|
-
response:
|
42
|
-
status:
|
43
|
-
code: 200
|
44
|
-
message: OK
|
45
|
-
headers:
|
46
|
-
Content-Length:
|
47
|
-
- "19"
|
48
|
-
body:
|
49
|
-
encoding: UTF-8
|
50
|
-
string: 2011-09-02 response
|
51
|
-
http_version: "1.1"
|
52
|
-
recorded_at: Tue, 01 Nov 2011 04:58:44 GMT
|
53
|
-
recorded_with: VCR 2.0.0
|
54
|
-
"""
|
55
|
-
|
56
|
-
Scenario Outline: Replay interaction that matches the query string
|
57
|
-
And a file named "query_matching.rb" with:
|
58
|
-
"""ruby
|
59
|
-
include_http_adapter_for("<http_lib>")
|
60
|
-
|
61
|
-
require 'vcr'
|
62
|
-
|
63
|
-
VCR.configure do |c|
|
64
|
-
<configuration>
|
65
|
-
c.default_cassette_options = { :match_requests_on => [:query] }
|
66
|
-
c.cassette_library_dir = 'cassettes'
|
67
|
-
end
|
68
|
-
|
69
|
-
VCR.use_cassette('example', :match_requests_on => [:query]) do
|
70
|
-
puts "Response for 2011-09-01 /query: " + response_body_for(:get, "http://example.com/query?date=2011-09-01")
|
71
|
-
end
|
72
|
-
|
73
|
-
VCR.use_cassette('example', :match_requests_on => [:query]) do
|
74
|
-
puts "Response for 2011-09-02 /query: " + response_body_for(:get, "http://example.com/query?date=2011-09-02")
|
75
|
-
end
|
76
|
-
"""
|
77
|
-
When I run `ruby query_matching.rb`
|
78
|
-
Then it should pass with:
|
79
|
-
"""
|
80
|
-
Response for 2011-09-01 /query: 2011-09-01 response
|
81
|
-
Response for 2011-09-02 /query: 2011-09-02 response
|
82
|
-
"""
|
83
|
-
|
84
|
-
Examples:
|
85
|
-
| configuration | http_lib |
|
86
|
-
| c.hook_into :fakeweb | net/http |
|
87
|
-
| c.hook_into :webmock | net/http |
|
88
|
-
| c.hook_into :webmock | httpclient |
|
89
|
-
| c.hook_into :webmock | curb |
|
90
|
-
| c.hook_into :webmock | patron |
|
91
|
-
| c.hook_into :webmock | em-http-request |
|
92
|
-
| c.hook_into :webmock | typhoeus |
|
93
|
-
| c.hook_into :typhoeus | typhoeus |
|
94
|
-
| c.hook_into :excon | excon |
|
95
|
-
| c.hook_into :faraday | faraday (w/ net_http) |
|
96
|
-
| c.hook_into :faraday | faraday (w/ typhoeus) |
|
97
|
-
|
@@ -1,94 +0,0 @@
|
|
1
|
-
Feature: Matching on URI
|
2
|
-
|
3
|
-
Use the `:uri` request matcher to match requests on the request URI.
|
4
|
-
|
5
|
-
The `:uri` matcher is used (along with the `:method` matcher) by default
|
6
|
-
if you do not specify how requests should match.
|
7
|
-
|
8
|
-
Background:
|
9
|
-
Given a previously recorded cassette file "cassettes/example.yml" with:
|
10
|
-
"""
|
11
|
-
---
|
12
|
-
http_interactions:
|
13
|
-
- request:
|
14
|
-
method: post
|
15
|
-
uri: http://example.com/foo
|
16
|
-
body:
|
17
|
-
encoding: UTF-8
|
18
|
-
string: ""
|
19
|
-
headers: {}
|
20
|
-
response:
|
21
|
-
status:
|
22
|
-
code: 200
|
23
|
-
message: OK
|
24
|
-
headers:
|
25
|
-
Content-Length:
|
26
|
-
- "12"
|
27
|
-
body:
|
28
|
-
encoding: UTF-8
|
29
|
-
string: foo response
|
30
|
-
http_version: "1.1"
|
31
|
-
recorded_at: Tue, 01 Nov 2011 04:58:44 GMT
|
32
|
-
- request:
|
33
|
-
method: post
|
34
|
-
uri: http://example.com/bar
|
35
|
-
body:
|
36
|
-
encoding: UTF-8
|
37
|
-
string: ""
|
38
|
-
headers: {}
|
39
|
-
response:
|
40
|
-
status:
|
41
|
-
code: 200
|
42
|
-
message: OK
|
43
|
-
headers:
|
44
|
-
Content-Length:
|
45
|
-
- "12"
|
46
|
-
body:
|
47
|
-
encoding: UTF-8
|
48
|
-
string: bar 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 Outline: Replay interaction that matches the request URI
|
55
|
-
And a file named "uri_matching.rb" with:
|
56
|
-
"""ruby
|
57
|
-
include_http_adapter_for("<http_lib>")
|
58
|
-
|
59
|
-
require 'vcr'
|
60
|
-
|
61
|
-
VCR.configure do |c|
|
62
|
-
<configuration>
|
63
|
-
c.cassette_library_dir = 'cassettes'
|
64
|
-
end
|
65
|
-
|
66
|
-
VCR.use_cassette('example', :match_requests_on => [:uri]) do
|
67
|
-
puts "Response for /bar: " + response_body_for(:get, "http://example.com/bar")
|
68
|
-
end
|
69
|
-
|
70
|
-
VCR.use_cassette('example', :match_requests_on => [:uri]) do
|
71
|
-
puts "Response for /foo: " + response_body_for(:get, "http://example.com/foo")
|
72
|
-
end
|
73
|
-
"""
|
74
|
-
When I run `ruby uri_matching.rb`
|
75
|
-
Then it should pass with:
|
76
|
-
"""
|
77
|
-
Response for /bar: bar response
|
78
|
-
Response for /foo: foo response
|
79
|
-
"""
|
80
|
-
|
81
|
-
Examples:
|
82
|
-
| configuration | http_lib |
|
83
|
-
| c.hook_into :fakeweb | net/http |
|
84
|
-
| c.hook_into :webmock | net/http |
|
85
|
-
| c.hook_into :webmock | httpclient |
|
86
|
-
| c.hook_into :webmock | curb |
|
87
|
-
| c.hook_into :webmock | patron |
|
88
|
-
| c.hook_into :webmock | em-http-request |
|
89
|
-
| c.hook_into :webmock | typhoeus |
|
90
|
-
| c.hook_into :typhoeus | typhoeus |
|
91
|
-
| c.hook_into :excon | excon |
|
92
|
-
| c.hook_into :faraday | faraday (w/ net_http) |
|
93
|
-
| c.hook_into :faraday | faraday (w/ typhoeus) |
|
94
|
-
|
@@ -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×tamp=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×tamp=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}×tamp=#{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
|