vcr 5.0.0 → 6.1.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/cassette/erb_renderer.rb +4 -2
- data/lib/vcr/cassette/migrator.rb +5 -1
- data/lib/vcr/cassette/persisters/file_system.rb +9 -1
- data/lib/vcr/cassette/serializers/json.rb +14 -8
- data/lib/vcr/cassette/serializers/psych.rb +10 -2
- data/lib/vcr/cassette/serializers/syck.rb +7 -1
- data/lib/vcr/cassette/serializers/yaml.rb +14 -2
- data/lib/vcr/cassette/serializers.rb +10 -0
- data/lib/vcr/cassette.rb +29 -7
- data/lib/vcr/configuration.rb +3 -1
- data/lib/vcr/library_hooks/typhoeus.rb +94 -111
- data/lib/vcr/library_hooks/webmock.rb +2 -11
- data/lib/vcr/linked_cassette.rb +4 -4
- data/lib/vcr/middleware/excon.rb +1 -1
- data/lib/vcr/middleware/faraday.rb +5 -0
- data/lib/vcr/request_ignorer.rb +4 -0
- data/lib/vcr/request_matcher_registry.rb +2 -2
- data/lib/vcr/structs.rb +7 -6
- data/lib/vcr/test_frameworks/cucumber.rb +16 -5
- data/lib/vcr/test_frameworks/rspec.rb +34 -22
- data/lib/vcr/version.rb +2 -2
- data/lib/vcr.rb +38 -8
- metadata +51 -37
- data/lib/vcr/library_hooks/typhoeus_0.4.rb +0 -103
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0230f475b5c666e17c97d0b81695860d18a54c40d07dccfb82ab63098fc60084
|
4
|
+
data.tar.gz: b79ad4ff6425ef66da8810b75f9cdc787d656c97cb5d60acf31c9ba09a4b6a5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 22d462bea8b4048575d82db89ecc36327be825267d76f69fa366ca98894b691210b6e859f4ab7d7acaf5fef537749b010ea166dcb09af642677bf402d6aaf855
|
7
|
+
data.tar.gz: 9f2a224345cabd78d03c0ac5f687b6261c7e1e34fe64c24dca7c4c46057de6122ec74d58c11ff3e3aefb8cc848efda899441c65c3d7dd0bdad86fbcccda9163d
|
@@ -32,7 +32,7 @@ module VCR
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def erb_variables
|
35
|
-
@erb if @erb.is_a?(Hash)
|
35
|
+
@erb if @erb.is_a?(Hash) && !@erb.empty?
|
36
36
|
end
|
37
37
|
|
38
38
|
def template
|
@@ -40,7 +40,9 @@ module VCR
|
|
40
40
|
end
|
41
41
|
|
42
42
|
@@struct_cache = Hash.new do |hash, attributes|
|
43
|
-
|
43
|
+
attributes = attributes.map(&:to_sym)
|
44
|
+
hash[attributes] = Struct.new(*attributes) unless hash.key?(attributes)
|
45
|
+
hash[attributes]
|
44
46
|
end
|
45
47
|
|
46
48
|
def variables_object
|
@@ -50,7 +50,11 @@ module VCR
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def load_yaml(cassette)
|
53
|
-
::YAML.
|
53
|
+
if ::YAML.respond_to?(:unsafe_load_file)
|
54
|
+
::YAML.unsafe_load_file(cassette)
|
55
|
+
else
|
56
|
+
::YAML.load_file(cassette)
|
57
|
+
end
|
54
58
|
rescue *@yaml_load_errors
|
55
59
|
return nil
|
56
60
|
end
|
@@ -55,7 +55,15 @@ module VCR
|
|
55
55
|
file_extension = '.' + parts.pop
|
56
56
|
end
|
57
57
|
|
58
|
-
parts.join('.').gsub(/[^[:word:]\-\/]+/, '_') + file_extension.to_s
|
58
|
+
file_name = parts.join('.').gsub(/[^[:word:]\-\/]+/, '_') + file_extension.to_s
|
59
|
+
file_name.downcase! if downcase_cassette_names?
|
60
|
+
file_name
|
61
|
+
end
|
62
|
+
|
63
|
+
def downcase_cassette_names?
|
64
|
+
!!VCR.configuration
|
65
|
+
.default_cassette_options
|
66
|
+
.dig(:persister_options, :downcase_cassette_names)
|
59
67
|
end
|
60
68
|
end
|
61
69
|
end
|
@@ -1,9 +1,9 @@
|
|
1
|
-
require '
|
1
|
+
require 'json'
|
2
2
|
|
3
3
|
module VCR
|
4
4
|
class Cassette
|
5
5
|
class Serializers
|
6
|
-
# The JSON serializer.
|
6
|
+
# The JSON serializer.
|
7
7
|
#
|
8
8
|
# @see Psych
|
9
9
|
# @see Syck
|
@@ -11,10 +11,14 @@ module VCR
|
|
11
11
|
module JSON
|
12
12
|
extend self
|
13
13
|
extend EncodingErrorHandling
|
14
|
+
extend SyntaxErrorHandling
|
14
15
|
|
15
16
|
# @private
|
16
|
-
ENCODING_ERRORS = [
|
17
|
-
ENCODING_ERRORS <<
|
17
|
+
ENCODING_ERRORS = [ArgumentError]
|
18
|
+
ENCODING_ERRORS << ::JSON::GeneratorError
|
19
|
+
|
20
|
+
# @private
|
21
|
+
SYNTAX_ERRORS = [::JSON::ParserError]
|
18
22
|
|
19
23
|
# The file extension to use for this serializer.
|
20
24
|
#
|
@@ -23,23 +27,25 @@ module VCR
|
|
23
27
|
"json"
|
24
28
|
end
|
25
29
|
|
26
|
-
# Serializes the given hash using `
|
30
|
+
# Serializes the given hash using `JSON`.
|
27
31
|
#
|
28
32
|
# @param [Hash] hash the object to serialize
|
29
33
|
# @return [String] the JSON string
|
30
34
|
def serialize(hash)
|
31
35
|
handle_encoding_errors do
|
32
|
-
|
36
|
+
::JSON.pretty_generate(hash)
|
33
37
|
end
|
34
38
|
end
|
35
39
|
|
36
|
-
# Deserializes the given string using `
|
40
|
+
# Deserializes the given string using `JSON`.
|
37
41
|
#
|
38
42
|
# @param [String] string the JSON string
|
39
43
|
# @return [Hash] the deserialized object
|
40
44
|
def deserialize(string)
|
41
45
|
handle_encoding_errors do
|
42
|
-
|
46
|
+
handle_syntax_errors do
|
47
|
+
::JSON.parse(string)
|
48
|
+
end
|
43
49
|
end
|
44
50
|
end
|
45
51
|
end
|
@@ -11,10 +11,14 @@ module VCR
|
|
11
11
|
module Psych
|
12
12
|
extend self
|
13
13
|
extend EncodingErrorHandling
|
14
|
+
extend SyntaxErrorHandling
|
14
15
|
|
15
16
|
# @private
|
16
17
|
ENCODING_ERRORS = [ArgumentError]
|
17
18
|
|
19
|
+
# @private
|
20
|
+
SYNTAX_ERRORS = [::Psych::SyntaxError]
|
21
|
+
|
18
22
|
# The file extension to use for this serializer.
|
19
23
|
#
|
20
24
|
# @return [String] "yml"
|
@@ -28,7 +32,9 @@ module VCR
|
|
28
32
|
# @return [String] the YAML string
|
29
33
|
def serialize(hash)
|
30
34
|
handle_encoding_errors do
|
31
|
-
::Psych.dump(hash)
|
35
|
+
result = ::Psych.dump(hash)
|
36
|
+
result.gsub!(": \n", ": null\n") # set canonical null value in order to avoid trailing whitespaces
|
37
|
+
result
|
32
38
|
end
|
33
39
|
end
|
34
40
|
|
@@ -38,7 +44,9 @@ module VCR
|
|
38
44
|
# @return [Hash] the deserialized object
|
39
45
|
def deserialize(string)
|
40
46
|
handle_encoding_errors do
|
41
|
-
|
47
|
+
handle_syntax_errors do
|
48
|
+
::Psych.load(string)
|
49
|
+
end
|
42
50
|
end
|
43
51
|
end
|
44
52
|
end
|
@@ -11,10 +11,14 @@ module VCR
|
|
11
11
|
module Syck
|
12
12
|
extend self
|
13
13
|
extend EncodingErrorHandling
|
14
|
+
extend SyntaxErrorHandling
|
14
15
|
|
15
16
|
# @private
|
16
17
|
ENCODING_ERRORS = [ArgumentError]
|
17
18
|
|
19
|
+
# @private
|
20
|
+
SYNTAX_ERRORS = [::Psych::SyntaxError]
|
21
|
+
|
18
22
|
# The file extension to use for this serializer.
|
19
23
|
#
|
20
24
|
# @return [String] "yml"
|
@@ -38,7 +42,9 @@ module VCR
|
|
38
42
|
# @return [Hash] the deserialized object
|
39
43
|
def deserialize(string)
|
40
44
|
handle_encoding_errors do
|
41
|
-
|
45
|
+
handle_syntax_errors do
|
46
|
+
using_syck { ::YAML.load(string) }
|
47
|
+
end
|
42
48
|
end
|
43
49
|
end
|
44
50
|
|
@@ -13,10 +13,14 @@ module VCR
|
|
13
13
|
module YAML
|
14
14
|
extend self
|
15
15
|
extend EncodingErrorHandling
|
16
|
+
extend SyntaxErrorHandling
|
16
17
|
|
17
18
|
# @private
|
18
19
|
ENCODING_ERRORS = [ArgumentError]
|
19
20
|
|
21
|
+
# @private
|
22
|
+
SYNTAX_ERRORS = [::Psych::SyntaxError]
|
23
|
+
|
20
24
|
# The file extension to use for this serializer.
|
21
25
|
#
|
22
26
|
# @return [String] "yml"
|
@@ -30,7 +34,9 @@ module VCR
|
|
30
34
|
# @return [String] the YAML string
|
31
35
|
def serialize(hash)
|
32
36
|
handle_encoding_errors do
|
33
|
-
::YAML.dump(hash)
|
37
|
+
result = ::YAML.dump(hash)
|
38
|
+
result.gsub!(": \n", ": null\n") # set canonical null value in order to avoid trailing whitespaces
|
39
|
+
result
|
34
40
|
end
|
35
41
|
end
|
36
42
|
|
@@ -40,7 +46,13 @@ module VCR
|
|
40
46
|
# @return [Hash] the deserialized object
|
41
47
|
def deserialize(string)
|
42
48
|
handle_encoding_errors do
|
43
|
-
|
49
|
+
handle_syntax_errors do
|
50
|
+
if ::YAML.respond_to?(:unsafe_load)
|
51
|
+
::YAML.unsafe_load(string)
|
52
|
+
else
|
53
|
+
::YAML.load(string)
|
54
|
+
end
|
55
|
+
end
|
44
56
|
end
|
45
57
|
end
|
46
58
|
end
|
@@ -54,6 +54,16 @@ module VCR
|
|
54
54
|
raise
|
55
55
|
end
|
56
56
|
end
|
57
|
+
|
58
|
+
# @private
|
59
|
+
module SyntaxErrorHandling
|
60
|
+
def handle_syntax_errors
|
61
|
+
yield
|
62
|
+
rescue *self::SYNTAX_ERRORS => e
|
63
|
+
e.message << "\nNote: This is a VCR cassette. If it is using ERB, you may have forgotten to pass the `:erb` option to `use_cassette`."
|
64
|
+
raise
|
65
|
+
end
|
66
|
+
end
|
57
67
|
end
|
58
68
|
end
|
59
69
|
|
data/lib/vcr/cassette.rb
CHANGED
@@ -24,6 +24,13 @@ module VCR
|
|
24
24
|
# plays them back, or does both.
|
25
25
|
attr_reader :record_mode
|
26
26
|
|
27
|
+
# @return [Boolean] The cassette's record_on_error mode. When the code that uses the cassette
|
28
|
+
# raises an error (for example a test failure) and record_on_error is set to false, no
|
29
|
+
# cassette will be recorded. This is useful when you are TDD'ing an API integration: when
|
30
|
+
# an error is raised that often means your request is invalid, so you don't want the cassette
|
31
|
+
# to be recorded.
|
32
|
+
attr_reader :record_on_error
|
33
|
+
|
27
34
|
# @return [Array<Symbol, #call>] List of request matchers. Used to find a response from an
|
28
35
|
# existing HTTP interaction to play back.
|
29
36
|
attr_reader :match_requests_on
|
@@ -66,13 +73,28 @@ module VCR
|
|
66
73
|
# @param (see VCR#eject_casssette)
|
67
74
|
# @see VCR#eject_cassette
|
68
75
|
def eject(options = {})
|
69
|
-
write_recorded_interactions_to_disk
|
76
|
+
write_recorded_interactions_to_disk if should_write_recorded_interactions_to_disk?
|
70
77
|
|
71
78
|
if should_assert_no_unused_interactions? && !options[:skip_no_unused_interactions_assertion]
|
72
79
|
http_interactions.assert_no_unused_interactions!
|
73
80
|
end
|
74
81
|
end
|
75
82
|
|
83
|
+
# @private
|
84
|
+
def run_failed!
|
85
|
+
@run_failed = true
|
86
|
+
end
|
87
|
+
|
88
|
+
# @private
|
89
|
+
def run_failed?
|
90
|
+
@run_failed = false unless defined?(@run_failed)
|
91
|
+
@run_failed
|
92
|
+
end
|
93
|
+
|
94
|
+
def should_write_recorded_interactions_to_disk?
|
95
|
+
!run_failed? || record_on_error
|
96
|
+
end
|
97
|
+
|
76
98
|
# @private
|
77
99
|
def http_interactions
|
78
100
|
# Without this mutex, under threaded access, an HTTPInteractionList will overwrite
|
@@ -151,10 +173,10 @@ module VCR
|
|
151
173
|
|
152
174
|
def assert_valid_options!
|
153
175
|
invalid_options = @options.keys - [
|
154
|
-
:record, :erb, :match_requests_on, :re_record_interval, :tag, :tags,
|
176
|
+
:record, :record_on_error, :erb, :match_requests_on, :re_record_interval, :tag, :tags,
|
155
177
|
:update_content_length_header, :allow_playback_repeats, :allow_unused_http_interactions,
|
156
178
|
:exclusive, :serialize_with, :preserve_exact_body_bytes, :decode_compressed_response,
|
157
|
-
:recompress_response, :persist_with, :clean_outdated_http_interactions
|
179
|
+
:recompress_response, :persist_with, :persister_options, :clean_outdated_http_interactions
|
158
180
|
]
|
159
181
|
|
160
182
|
if invalid_options.size > 0
|
@@ -163,17 +185,16 @@ module VCR
|
|
163
185
|
end
|
164
186
|
|
165
187
|
def extract_options
|
166
|
-
[:erb, :match_requests_on, :re_record_interval, :clean_outdated_http_interactions,
|
188
|
+
[:record_on_error, :erb, :match_requests_on, :re_record_interval, :clean_outdated_http_interactions,
|
167
189
|
:allow_playback_repeats, :allow_unused_http_interactions, :exclusive].each do |name|
|
168
190
|
instance_variable_set("@#{name}", @options[name])
|
169
191
|
end
|
170
192
|
|
171
193
|
assign_tags
|
172
194
|
|
173
|
-
@record_mode = @options[:record]
|
174
195
|
@serializer = VCR.cassette_serializers[@options[:serialize_with]]
|
175
196
|
@persister = VCR.cassette_persisters[@options[:persist_with]]
|
176
|
-
@record_mode = :all
|
197
|
+
@record_mode = should_re_record?(@options[:record]) ? :all : @options[:record]
|
177
198
|
@parent_list = @exclusive ? HTTPInteractionList::NullList : VCR.http_interactions
|
178
199
|
end
|
179
200
|
|
@@ -209,9 +230,10 @@ module VCR
|
|
209
230
|
end
|
210
231
|
end
|
211
232
|
|
212
|
-
def should_re_record?
|
233
|
+
def should_re_record?(record_mode)
|
213
234
|
return false unless @re_record_interval
|
214
235
|
return false unless originally_recorded_at
|
236
|
+
return false if record_mode == :none
|
215
237
|
|
216
238
|
now = Time.now
|
217
239
|
|
data/lib/vcr/configuration.rb
CHANGED
@@ -492,10 +492,12 @@ module VCR
|
|
492
492
|
@rspec_metadata_configured = false
|
493
493
|
@default_cassette_options = {
|
494
494
|
:record => :once,
|
495
|
+
:record_on_error => true,
|
495
496
|
:match_requests_on => RequestMatcherRegistry::DEFAULT_MATCHERS,
|
496
497
|
:allow_unused_http_interactions => true,
|
497
498
|
:serialize_with => :yaml,
|
498
|
-
:persist_with => :file_system
|
499
|
+
:persist_with => :file_system,
|
500
|
+
:persister_options => {}
|
499
501
|
}
|
500
502
|
|
501
503
|
self.uri_parser = URI
|
@@ -2,137 +2,121 @@ require 'vcr/util/version_checker'
|
|
2
2
|
require 'vcr/request_handler'
|
3
3
|
require 'typhoeus'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
module VCR
|
11
|
-
class LibraryHooks
|
5
|
+
module VCR
|
6
|
+
class LibraryHooks
|
7
|
+
# @private
|
8
|
+
module Typhoeus
|
12
9
|
# @private
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
request.block_connection = false if VCR.turned_on?
|
20
|
-
end
|
21
|
-
|
22
|
-
def vcr_request
|
23
|
-
@vcr_request ||= VCR::Request.new \
|
24
|
-
request.options.fetch(:method, :get),
|
25
|
-
request.url,
|
26
|
-
request_body,
|
27
|
-
request.options.fetch(:headers, {})
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
10
|
+
class RequestHandler < ::VCR::RequestHandler
|
11
|
+
attr_reader :request
|
12
|
+
def initialize(request)
|
13
|
+
@request = request
|
14
|
+
request.block_connection = false if VCR.turned_on?
|
15
|
+
end
|
31
16
|
|
32
|
-
|
33
|
-
|
34
|
-
|
17
|
+
def vcr_request
|
18
|
+
@vcr_request ||= VCR::Request.new \
|
19
|
+
request.options.fetch(:method, :get),
|
20
|
+
request.url,
|
21
|
+
request.encoded_body,
|
22
|
+
request.options.fetch(:headers, {})
|
23
|
+
end
|
35
24
|
|
36
|
-
|
37
|
-
super
|
38
|
-
request.instance_variable_set(:@__typed_vcr_request, @after_hook_typed_request)
|
39
|
-
end
|
25
|
+
private
|
40
26
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
end
|
27
|
+
def externally_stubbed?
|
28
|
+
::Typhoeus::Expectation.find_by(request)
|
29
|
+
end
|
45
30
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
:status_message => stubbed_response.status.message,
|
51
|
-
:headers => stubbed_response_headers,
|
52
|
-
:body => stubbed_response.body,
|
53
|
-
:effective_url => stubbed_response.adapter_metadata.fetch('effective_url', request.url),
|
54
|
-
:mock => true
|
55
|
-
|
56
|
-
first_header_line = "HTTP/#{stubbed_response.http_version} #{response.code} #{response.status_message}\r\n"
|
57
|
-
response.instance_variable_set(:@first_header_line, first_header_line)
|
58
|
-
response.instance_variable_get(:@options)[:response_headers] =
|
59
|
-
first_header_line + response.headers.map { |k,v| "#{k}: #{v}"}.join("\r\n")
|
60
|
-
|
61
|
-
response
|
62
|
-
end
|
31
|
+
def set_typed_request_for_after_hook(*args)
|
32
|
+
super
|
33
|
+
request.instance_variable_set(:@__typed_vcr_request, @after_hook_typed_request)
|
34
|
+
end
|
63
35
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
end if stubbed_response.headers
|
69
|
-
end
|
70
|
-
end
|
36
|
+
def on_unhandled_request
|
37
|
+
invoke_after_request_hook(nil)
|
38
|
+
super
|
39
|
+
end
|
71
40
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
41
|
+
def on_stubbed_by_vcr_request
|
42
|
+
response = ::Typhoeus::Response.new \
|
43
|
+
:http_version => stubbed_response.http_version,
|
44
|
+
:code => stubbed_response.status.code,
|
45
|
+
:status_message => stubbed_response.status.message,
|
46
|
+
:headers => stubbed_response_headers,
|
47
|
+
:body => stubbed_response.body,
|
48
|
+
:effective_url => stubbed_response.adapter_metadata.fetch('effective_url', request.url),
|
49
|
+
:mock => true
|
50
|
+
|
51
|
+
first_header_line = "HTTP/#{stubbed_response.http_version} #{response.code} #{response.status_message}\r\n"
|
52
|
+
response.instance_variable_set(:@first_header_line, first_header_line)
|
53
|
+
response.instance_variable_get(:@options)[:response_headers] =
|
54
|
+
first_header_line + response.headers.map { |k,v| "#{k}: #{v}"}.join("\r\n")
|
55
|
+
|
56
|
+
response
|
81
57
|
end
|
82
58
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
response.headers,
|
89
|
-
response.body,
|
90
|
-
response.http_version,
|
91
|
-
{ "effective_url" => response.effective_url }
|
59
|
+
def stubbed_response_headers
|
60
|
+
@stubbed_response_headers ||= {}.tap do |hash|
|
61
|
+
stubbed_response.headers.each do |key, values|
|
62
|
+
hash[key] = values.size == 1 ? values.first : values
|
63
|
+
end if stubbed_response.headers
|
92
64
|
end
|
65
|
+
end
|
66
|
+
end
|
93
67
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
68
|
+
# @private
|
69
|
+
class << self
|
70
|
+
def vcr_response_from(response)
|
71
|
+
VCR::Response.new \
|
72
|
+
VCR::ResponseStatus.new(response.code, response.status_message),
|
73
|
+
response.headers,
|
74
|
+
response.body,
|
75
|
+
response.http_version,
|
76
|
+
{ "effective_url" => response.effective_url }
|
77
|
+
end
|
103
78
|
|
104
|
-
|
105
|
-
|
106
|
-
|
79
|
+
def collect_chunks(request)
|
80
|
+
chunks = ''
|
81
|
+
request.on_body.unshift(
|
82
|
+
Proc.new do |body, response|
|
83
|
+
chunks += body
|
84
|
+
request.instance_variable_set(:@chunked_body, chunks)
|
85
|
+
end
|
86
|
+
)
|
107
87
|
end
|
108
88
|
|
109
|
-
|
110
|
-
|
89
|
+
def restore_body_from_chunks(response, request)
|
90
|
+
response.options[:response_body] = request.instance_variable_get(:@chunked_body)
|
91
|
+
end
|
92
|
+
end
|
111
93
|
|
112
|
-
|
94
|
+
::Typhoeus.on_complete do |response|
|
95
|
+
request = response.request
|
113
96
|
|
114
|
-
|
115
|
-
vcr_response = vcr_response_from(response)
|
116
|
-
typed_vcr_request = request.send(:remove_instance_variable, :@__typed_vcr_request)
|
97
|
+
restore_body_from_chunks(response, request) if request.streaming?
|
117
98
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
end
|
99
|
+
unless VCR.library_hooks.disabled?(:typhoeus)
|
100
|
+
vcr_response = vcr_response_from(response)
|
101
|
+
typed_vcr_request = request.send(:remove_instance_variable, :@__typed_vcr_request)
|
122
102
|
|
123
|
-
|
103
|
+
unless request.response.mock
|
104
|
+
http_interaction = VCR::HTTPInteraction.new(typed_vcr_request, vcr_response)
|
105
|
+
VCR.record_http_interaction(http_interaction)
|
124
106
|
end
|
107
|
+
|
108
|
+
VCR.configuration.invoke_hook(:after_http_request, typed_vcr_request, vcr_response)
|
125
109
|
end
|
110
|
+
end
|
126
111
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
end
|
112
|
+
::Typhoeus.before do |request|
|
113
|
+
collect_chunks(request) if request.streaming?
|
114
|
+
if response = VCR::LibraryHooks::Typhoeus::RequestHandler.new(request).handle
|
115
|
+
request.on_headers.each { |cb| cb.call(response) }
|
116
|
+
request.on_body.each { |cb| cb.call(response.body, response) }
|
117
|
+
request.finish(response)
|
118
|
+
else
|
119
|
+
true
|
136
120
|
end
|
137
121
|
end
|
138
122
|
end
|
@@ -146,4 +130,3 @@ VCR.configuration.after_library_hooks_loaded do
|
|
146
130
|
WebMock::HttpLibAdapters::TyphoeusAdapter.disable!
|
147
131
|
end
|
148
132
|
end
|
149
|
-
|
@@ -12,8 +12,6 @@ module VCR
|
|
12
12
|
module WebMock
|
13
13
|
extend self
|
14
14
|
|
15
|
-
@global_hook_disabled_requests = {}
|
16
|
-
|
17
15
|
def with_global_hook_disabled(request)
|
18
16
|
global_hook_disabled_requests << request
|
19
17
|
|
@@ -25,19 +23,12 @@ module VCR
|
|
25
23
|
end
|
26
24
|
|
27
25
|
def global_hook_disabled?(request)
|
28
|
-
requests =
|
26
|
+
requests = Thread.current[:_vcr_webmock_disabled_requests]
|
29
27
|
requests && requests.include?(request)
|
30
28
|
end
|
31
29
|
|
32
30
|
def global_hook_disabled_requests
|
33
|
-
|
34
|
-
return requests if requests
|
35
|
-
|
36
|
-
ObjectSpace.define_finalizer(Thread.current, lambda {
|
37
|
-
@global_hook_disabled_requests.delete(Thread.current.object_id)
|
38
|
-
})
|
39
|
-
|
40
|
-
@global_hook_disabled_requests[Thread.current.object_id] = []
|
31
|
+
Thread.current[:_vcr_webmock_disabled_requests] ||= []
|
41
32
|
end
|
42
33
|
|
43
34
|
# @private
|
data/lib/vcr/linked_cassette.rb
CHANGED
@@ -9,8 +9,8 @@ module VCR
|
|
9
9
|
include Enumerable
|
10
10
|
|
11
11
|
# Creates a new list of context-owned cassettes and linked cassettes
|
12
|
-
# @param [Array] context-owned cassettes
|
13
|
-
# @param [Array] context-unowned (linked) cassettes
|
12
|
+
# @param cassettes [Array] context-owned cassettes
|
13
|
+
# @param linked_cassettes [Array] context-unowned (linked) cassettes
|
14
14
|
def initialize(cassettes, linked_cassettes)
|
15
15
|
@cassettes = cassettes
|
16
16
|
@linked_cassettes = linked_cassettes
|
@@ -52,8 +52,8 @@ module VCR
|
|
52
52
|
end
|
53
53
|
|
54
54
|
# Create a new CassetteList
|
55
|
-
# @param [Array] context-owned cassettes
|
56
|
-
# @param [Array] context-unowned (linked) cassettes
|
55
|
+
# @param cassettes [Array] context-owned cassettes
|
56
|
+
# @param linked_cassettes [Array] context-unowned (linked) cassettes
|
57
57
|
def self.list(cassettes, linked_cassettes)
|
58
58
|
CassetteList.new(cassettes, linked_cassettes)
|
59
59
|
end
|
data/lib/vcr/middleware/excon.rb
CHANGED
data/lib/vcr/request_ignorer.rb
CHANGED
@@ -110,12 +110,12 @@ module VCR
|
|
110
110
|
|
111
111
|
def register_built_ins
|
112
112
|
register(:method) { |r1, r2| r1.method == r2.method }
|
113
|
-
register(:uri) { |r1, r2| r1.
|
113
|
+
register(:uri) { |r1, r2| r1.parsed_uri == r2.parsed_uri }
|
114
114
|
register(:body) { |r1, r2| r1.body == r2.body }
|
115
115
|
register(:headers) { |r1, r2| r1.headers == r2.headers }
|
116
116
|
|
117
117
|
register(:host) do |r1, r2|
|
118
|
-
r1.parsed_uri.host == r2.parsed_uri.host
|
118
|
+
r1.parsed_uri.host.chomp('.') == r2.parsed_uri.host.chomp('.')
|
119
119
|
end
|
120
120
|
register(:path) do |r1, r2|
|
121
121
|
r1.parsed_uri.path == r2.parsed_uri.path
|
data/lib/vcr/structs.rb
CHANGED
@@ -62,7 +62,7 @@ module VCR
|
|
62
62
|
super
|
63
63
|
|
64
64
|
if body && !body.is_a?(String)
|
65
|
-
raise ArgumentError, "#{self.class} initialized with an invalid body: #{body.inspect}."
|
65
|
+
raise ArgumentError, "#{self.class} initialized with an invalid (non-String) body of class #{body.class}: #{body.inspect}."
|
66
66
|
end
|
67
67
|
|
68
68
|
# Ensure that the body is a raw string, in case the string instance
|
@@ -346,9 +346,9 @@ module VCR
|
|
346
346
|
{
|
347
347
|
'status' => status.to_hash,
|
348
348
|
'headers' => headers,
|
349
|
-
'body' => serializable_body
|
350
|
-
'http_version' => http_version
|
349
|
+
'body' => serializable_body
|
351
350
|
}.tap do |hash|
|
351
|
+
hash['http_version'] = http_version if http_version
|
352
352
|
hash['adapter_metadata'] = adapter_metadata unless adapter_metadata.empty?
|
353
353
|
end
|
354
354
|
end
|
@@ -454,9 +454,10 @@ module VCR
|
|
454
454
|
|
455
455
|
case type
|
456
456
|
when 'gzip'
|
457
|
-
|
458
|
-
|
459
|
-
yield Zlib::GzipReader.new(
|
457
|
+
gzip_reader_options = {}
|
458
|
+
gzip_reader_options[:encoding] = 'ASCII-8BIT' if ''.respond_to?(:encoding)
|
459
|
+
yield Zlib::GzipReader.new(StringIO.new(body),
|
460
|
+
**gzip_reader_options).read
|
460
461
|
when 'deflate'
|
461
462
|
yield Zlib::Inflate.inflate(body)
|
462
463
|
when 'identity', NilClass
|
@@ -23,10 +23,10 @@ module VCR
|
|
23
23
|
# Adds `Before` and `After` cucumber hooks for the named tags that
|
24
24
|
# will cause a VCR cassette to be used for scenarios with matching tags.
|
25
25
|
#
|
26
|
-
# @param [Array<String>]
|
27
|
-
#
|
28
|
-
# `:use_scenario_name => true` to automatically name the
|
29
|
-
#
|
26
|
+
# @param tag_names [Array<String,Hash>] the cucumber scenario tags. If
|
27
|
+
# the last argument is a hash it is treated as cassette options.
|
28
|
+
# - `:use_scenario_name => true` to automatically name the
|
29
|
+
# cassette according to the scenario name.
|
30
30
|
def tags(*tag_names)
|
31
31
|
original_options = tag_names.last.is_a?(::Hash) ? tag_names.pop : {}
|
32
32
|
tag_names.each do |tag_name|
|
@@ -47,10 +47,21 @@ module VCR
|
|
47
47
|
scenario.scenario_outline.name,
|
48
48
|
scenario.name.split("\n").first
|
49
49
|
].join("/")
|
50
|
-
|
50
|
+
elsif scenario.respond_to?(:feature)
|
51
51
|
[ scenario.feature.name.split("\n").first,
|
52
52
|
scenario.name.split("\n").first
|
53
53
|
].join("/")
|
54
|
+
elsif scenario.location.lines.min == scenario.location.lines.max
|
55
|
+
# test case from a regular scenario in cucumber version 4
|
56
|
+
[ scenario.location.file.split("/").last.split(".").first,
|
57
|
+
scenario.name.split("\n").first
|
58
|
+
].join("/")
|
59
|
+
else
|
60
|
+
# test case from a scenario with examples ("scenario outline") in cucumber version 4
|
61
|
+
[ scenario.location.file.split("/").last.split(".").first,
|
62
|
+
scenario.name.split("\n").first,
|
63
|
+
"Example at line #{scenario.location.lines.max}"
|
64
|
+
].join("/")
|
54
65
|
end
|
55
66
|
else
|
56
67
|
"cucumber_tags/#{tag_name.gsub(/\A@/, '')}"
|
@@ -5,38 +5,50 @@ module VCR
|
|
5
5
|
module Metadata
|
6
6
|
extend self
|
7
7
|
|
8
|
+
def vcr_cassette_name_for(metadata)
|
9
|
+
description =
|
10
|
+
if metadata[:description].empty?
|
11
|
+
# we have an "it { is_expected.to be something }" block
|
12
|
+
metadata[:scoped_id]
|
13
|
+
else
|
14
|
+
metadata[:description]
|
15
|
+
end
|
16
|
+
example_group =
|
17
|
+
if metadata.key?(:example_group)
|
18
|
+
metadata[:example_group]
|
19
|
+
else
|
20
|
+
metadata[:parent_example_group]
|
21
|
+
end
|
22
|
+
|
23
|
+
if example_group
|
24
|
+
[vcr_cassette_name_for(example_group), description].join('/')
|
25
|
+
else
|
26
|
+
description
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
8
30
|
def configure!
|
9
31
|
::RSpec.configure do |config|
|
10
|
-
vcr_cassette_name_for = lambda do |metadata|
|
11
|
-
description = if metadata[:description].empty?
|
12
|
-
# we have an "it { is_expected.to be something }" block
|
13
|
-
metadata[:scoped_id]
|
14
|
-
else
|
15
|
-
metadata[:description]
|
16
|
-
end
|
17
|
-
example_group = if metadata.key?(:example_group)
|
18
|
-
metadata[:example_group]
|
19
|
-
else
|
20
|
-
metadata[:parent_example_group]
|
21
|
-
end
|
22
|
-
|
23
|
-
if example_group
|
24
|
-
[vcr_cassette_name_for[example_group], description].join('/')
|
25
|
-
else
|
26
|
-
description
|
27
|
-
end
|
28
|
-
end
|
29
32
|
|
30
33
|
when_tagged_with_vcr = { :vcr => lambda { |v| !!v } }
|
31
34
|
|
32
35
|
config.before(:each, when_tagged_with_vcr) do |ex|
|
33
36
|
example = ex.respond_to?(:metadata) ? ex : ex.example
|
34
37
|
|
38
|
+
cassette_name = nil
|
35
39
|
options = example.metadata[:vcr]
|
36
|
-
options =
|
40
|
+
options = case options
|
41
|
+
when Hash #=> vcr: { cassette_name: 'foo' }
|
42
|
+
options.dup
|
43
|
+
when String #=> vcr: 'bar'
|
44
|
+
cassette_name = options.dup
|
45
|
+
{}
|
46
|
+
else #=> :vcr or vcr: true
|
47
|
+
{}
|
48
|
+
end
|
37
49
|
|
38
|
-
cassette_name
|
39
|
-
|
50
|
+
cassette_name ||= options.delete(:cassette_name) ||
|
51
|
+
VCR::RSpec::Metadata.vcr_cassette_name_for(example.metadata)
|
40
52
|
VCR.insert_cassette(cassette_name, options)
|
41
53
|
end
|
42
54
|
|
data/lib/vcr/version.rb
CHANGED
@@ -10,7 +10,7 @@ module VCR
|
|
10
10
|
# * `parts` [Array<Integer>] List of the version parts.
|
11
11
|
def version
|
12
12
|
@version ||= begin
|
13
|
-
string = '
|
13
|
+
string = +'6.1.0'
|
14
14
|
|
15
15
|
def string.parts
|
16
16
|
split('.').map { |p| p.to_i }
|
@@ -28,7 +28,7 @@ module VCR
|
|
28
28
|
parts[2]
|
29
29
|
end
|
30
30
|
|
31
|
-
string
|
31
|
+
string.freeze
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
data/lib/vcr.rb
CHANGED
@@ -52,7 +52,7 @@ module VCR
|
|
52
52
|
# Inserts the named cassette using the given cassette options.
|
53
53
|
# New HTTP interactions, if allowed by the cassette's `:record` option, will
|
54
54
|
# be recorded to the cassette. The cassette's existing HTTP interactions
|
55
|
-
# will be used to stub requests, unless prevented by the
|
55
|
+
# will be used to stub requests, unless prevented by the cassette's
|
56
56
|
# `:record` option.
|
57
57
|
#
|
58
58
|
# @example
|
@@ -107,6 +107,12 @@ module VCR
|
|
107
107
|
# @option options :persist_with [Symbol] Which cassette persister to
|
108
108
|
# use. Defaults to :file_system. You can also register and use a
|
109
109
|
# custom persister.
|
110
|
+
# @option options :persister_options [Hash] Pass options to the
|
111
|
+
# persister specified in `persist_with`. Currently available options for the file_system persister:
|
112
|
+
# - `:downcase_cassette_names`: when `true`, names of cassettes will be
|
113
|
+
# normalized in lowercase before reading and writing, which can avoid
|
114
|
+
# confusion when using both case-sensitive and case-insensitive file
|
115
|
+
# systems.
|
110
116
|
# @option options :preserve_exact_body_bytes [Boolean] Whether or not
|
111
117
|
# to base64 encode the bytes of the requests and responses for this cassette
|
112
118
|
# when serializing it. See also `VCR::Configuration#preserve_exact_body_bytes`.
|
@@ -186,6 +192,9 @@ module VCR
|
|
186
192
|
|
187
193
|
begin
|
188
194
|
call_block(block, cassette)
|
195
|
+
rescue StandardError
|
196
|
+
cassette.run_failed!
|
197
|
+
raise
|
189
198
|
ensure
|
190
199
|
eject_cassette
|
191
200
|
end
|
@@ -194,13 +203,13 @@ module VCR
|
|
194
203
|
# Inserts multiple cassettes the given names
|
195
204
|
#
|
196
205
|
# @example
|
197
|
-
#
|
198
|
-
#
|
199
|
-
#
|
200
|
-
#
|
201
|
-
#
|
202
|
-
#
|
203
|
-
#
|
206
|
+
# cassettes = [
|
207
|
+
# { name: 'github' },
|
208
|
+
# { name: 'apple', options: { erb: true } }
|
209
|
+
# ]
|
210
|
+
# VCR.use_cassettes(cassettes) do
|
211
|
+
# # make multiple HTTP requests
|
212
|
+
# end
|
204
213
|
def use_cassettes(cassettes, &block)
|
205
214
|
cassette = cassettes.pop
|
206
215
|
use_cassette(cassette[:name], cassette[:options] || {}) do
|
@@ -257,6 +266,7 @@ module VCR
|
|
257
266
|
# @see #turn_off!
|
258
267
|
# @see #turn_on!
|
259
268
|
# @see #turned_on?
|
269
|
+
# @see #turned_on
|
260
270
|
def turned_off(options = {})
|
261
271
|
turn_off!(options)
|
262
272
|
|
@@ -292,11 +302,28 @@ module VCR
|
|
292
302
|
set_context_value(:turned_off, true)
|
293
303
|
end
|
294
304
|
|
305
|
+
# Turns on VCR, for the duration of a block.
|
306
|
+
# @param (see #turn_off!)
|
307
|
+
# @return [void]
|
308
|
+
# @see #turn_off!
|
309
|
+
# @see #turned_off
|
310
|
+
# @see #turned_on?
|
311
|
+
def turned_on(options = {})
|
312
|
+
turn_on!
|
313
|
+
|
314
|
+
begin
|
315
|
+
yield
|
316
|
+
ensure
|
317
|
+
turn_off!(options)
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
295
321
|
# Turns on VCR, if it has previously been turned off.
|
296
322
|
# @return [void]
|
297
323
|
# @see #turn_off!
|
298
324
|
# @see #turned_off
|
299
325
|
# @see #turned_on?
|
326
|
+
# @see #turned_on
|
300
327
|
def turn_on!
|
301
328
|
set_context_value(:turned_off, false)
|
302
329
|
end
|
@@ -308,6 +335,9 @@ module VCR
|
|
308
335
|
# @see #turn_off!
|
309
336
|
# @see #turned_off
|
310
337
|
def turned_on?
|
338
|
+
linked_context = current_context[:linked_context]
|
339
|
+
return !linked_context[:turned_off] if linked_context
|
340
|
+
|
311
341
|
!context_value(:turned_off)
|
312
342
|
end
|
313
343
|
|
metadata
CHANGED
@@ -1,14 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vcr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 6.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Myron Marston
|
8
|
-
|
8
|
+
- Kurtis Rainbolt-Greene
|
9
|
+
- Olle Jonsson
|
10
|
+
autorequire:
|
9
11
|
bindir: bin
|
10
12
|
cert_chain: []
|
11
|
-
date:
|
13
|
+
date: 2022-03-13 00:00:00.000000000 Z
|
12
14
|
dependencies:
|
13
15
|
- !ruby/object:Gem::Dependency
|
14
16
|
name: bundler
|
@@ -44,28 +46,28 @@ dependencies:
|
|
44
46
|
requirements:
|
45
47
|
- - "~>"
|
46
48
|
- !ruby/object:Gem::Version
|
47
|
-
version: 3.
|
49
|
+
version: 3.4.4
|
48
50
|
type: :development
|
49
51
|
prerelease: false
|
50
52
|
version_requirements: !ruby/object:Gem::Requirement
|
51
53
|
requirements:
|
52
54
|
- - "~>"
|
53
55
|
- !ruby/object:Gem::Version
|
54
|
-
version: 3.
|
56
|
+
version: 3.4.4
|
55
57
|
- !ruby/object:Gem::Dependency
|
56
58
|
name: rake
|
57
59
|
requirement: !ruby/object:Gem::Requirement
|
58
60
|
requirements:
|
59
|
-
- - "
|
61
|
+
- - ">="
|
60
62
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
63
|
+
version: 12.3.3
|
62
64
|
type: :development
|
63
65
|
prerelease: false
|
64
66
|
version_requirements: !ruby/object:Gem::Requirement
|
65
67
|
requirements:
|
66
|
-
- - "
|
68
|
+
- - ">="
|
67
69
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
70
|
+
version: 12.3.3
|
69
71
|
- !ruby/object:Gem::Dependency
|
70
72
|
name: pry
|
71
73
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,48 +152,74 @@ dependencies:
|
|
150
152
|
- - ">="
|
151
153
|
- !ruby/object:Gem::Version
|
152
154
|
version: '0'
|
155
|
+
- !ruby/object:Gem::Dependency
|
156
|
+
name: hashdiff
|
157
|
+
requirement: !ruby/object:Gem::Requirement
|
158
|
+
requirements:
|
159
|
+
- - ">="
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: 1.0.0.beta1
|
162
|
+
- - "<"
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: 2.0.0
|
165
|
+
type: :development
|
166
|
+
prerelease: false
|
167
|
+
version_requirements: !ruby/object:Gem::Requirement
|
168
|
+
requirements:
|
169
|
+
- - ">="
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: 1.0.0.beta1
|
172
|
+
- - "<"
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: 2.0.0
|
153
175
|
- !ruby/object:Gem::Dependency
|
154
176
|
name: cucumber
|
155
177
|
requirement: !ruby/object:Gem::Requirement
|
156
178
|
requirements:
|
157
179
|
- - "~>"
|
158
180
|
- !ruby/object:Gem::Version
|
159
|
-
version:
|
181
|
+
version: '7.0'
|
160
182
|
type: :development
|
161
183
|
prerelease: false
|
162
184
|
version_requirements: !ruby/object:Gem::Requirement
|
163
185
|
requirements:
|
164
186
|
- - "~>"
|
165
187
|
- !ruby/object:Gem::Version
|
166
|
-
version:
|
188
|
+
version: '7.0'
|
167
189
|
- !ruby/object:Gem::Dependency
|
168
190
|
name: aruba
|
169
191
|
requirement: !ruby/object:Gem::Requirement
|
170
192
|
requirements:
|
171
193
|
- - "~>"
|
172
194
|
- !ruby/object:Gem::Version
|
173
|
-
version: 0.
|
195
|
+
version: 0.14.14
|
174
196
|
type: :development
|
175
197
|
prerelease: false
|
176
198
|
version_requirements: !ruby/object:Gem::Requirement
|
177
199
|
requirements:
|
178
200
|
- - "~>"
|
179
201
|
- !ruby/object:Gem::Version
|
180
|
-
version: 0.
|
202
|
+
version: 0.14.14
|
181
203
|
- !ruby/object:Gem::Dependency
|
182
204
|
name: faraday
|
183
205
|
requirement: !ruby/object:Gem::Requirement
|
184
206
|
requirements:
|
185
|
-
- - "
|
207
|
+
- - ">="
|
186
208
|
- !ruby/object:Gem::Version
|
187
209
|
version: 0.11.0
|
210
|
+
- - "<"
|
211
|
+
- !ruby/object:Gem::Version
|
212
|
+
version: 2.0.0
|
188
213
|
type: :development
|
189
214
|
prerelease: false
|
190
215
|
version_requirements: !ruby/object:Gem::Requirement
|
191
216
|
requirements:
|
192
|
-
- - "
|
217
|
+
- - ">="
|
193
218
|
- !ruby/object:Gem::Version
|
194
219
|
version: 0.11.0
|
220
|
+
- - "<"
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: 2.0.0
|
195
223
|
- !ruby/object:Gem::Dependency
|
196
224
|
name: httpclient
|
197
225
|
requirement: !ruby/object:Gem::Requirement
|
@@ -210,14 +238,14 @@ dependencies:
|
|
210
238
|
name: excon
|
211
239
|
requirement: !ruby/object:Gem::Requirement
|
212
240
|
requirements:
|
213
|
-
- -
|
241
|
+
- - ">="
|
214
242
|
- !ruby/object:Gem::Version
|
215
243
|
version: 0.62.0
|
216
244
|
type: :development
|
217
245
|
prerelease: false
|
218
246
|
version_requirements: !ruby/object:Gem::Requirement
|
219
247
|
requirements:
|
220
|
-
- -
|
248
|
+
- - ">="
|
221
249
|
- !ruby/object:Gem::Version
|
222
250
|
version: 0.62.0
|
223
251
|
- !ruby/object:Gem::Dependency
|
@@ -234,20 +262,6 @@ dependencies:
|
|
234
262
|
- - ">="
|
235
263
|
- !ruby/object:Gem::Version
|
236
264
|
version: '0'
|
237
|
-
- !ruby/object:Gem::Dependency
|
238
|
-
name: multi_json
|
239
|
-
requirement: !ruby/object:Gem::Requirement
|
240
|
-
requirements:
|
241
|
-
- - ">="
|
242
|
-
- !ruby/object:Gem::Version
|
243
|
-
version: '0'
|
244
|
-
type: :development
|
245
|
-
prerelease: false
|
246
|
-
version_requirements: !ruby/object:Gem::Requirement
|
247
|
-
requirements:
|
248
|
-
- - ">="
|
249
|
-
- !ruby/object:Gem::Version
|
250
|
-
version: '0'
|
251
265
|
- !ruby/object:Gem::Dependency
|
252
266
|
name: json
|
253
267
|
requirement: !ruby/object:Gem::Requirement
|
@@ -307,7 +321,7 @@ dependencies:
|
|
307
321
|
description: Record your test suite's HTTP interactions and replay them during future
|
308
322
|
test runs for fast, deterministic, accurate tests.
|
309
323
|
email:
|
310
|
-
-
|
324
|
+
- kurtis@rainbolt-greene.online
|
311
325
|
executables: []
|
312
326
|
extensions: []
|
313
327
|
extra_rdoc_files: []
|
@@ -332,7 +346,6 @@ files:
|
|
332
346
|
- lib/vcr/library_hooks/excon.rb
|
333
347
|
- lib/vcr/library_hooks/faraday.rb
|
334
348
|
- lib/vcr/library_hooks/typhoeus.rb
|
335
|
-
- lib/vcr/library_hooks/typhoeus_0.4.rb
|
336
349
|
- lib/vcr/library_hooks/webmock.rb
|
337
350
|
- lib/vcr/linked_cassette.rb
|
338
351
|
- lib/vcr/middleware/excon.rb
|
@@ -354,9 +367,10 @@ files:
|
|
354
367
|
- lib/vcr/version.rb
|
355
368
|
homepage: https://relishapp.com/vcr/vcr/docs
|
356
369
|
licenses:
|
370
|
+
- Hippocratic-2.1
|
357
371
|
- MIT
|
358
372
|
metadata: {}
|
359
|
-
post_install_message:
|
373
|
+
post_install_message:
|
360
374
|
rdoc_options: []
|
361
375
|
require_paths:
|
362
376
|
- lib
|
@@ -364,15 +378,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
364
378
|
requirements:
|
365
379
|
- - ">="
|
366
380
|
- !ruby/object:Gem::Version
|
367
|
-
version:
|
381
|
+
version: '2.6'
|
368
382
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
369
383
|
requirements:
|
370
384
|
- - ">="
|
371
385
|
- !ruby/object:Gem::Version
|
372
386
|
version: '0'
|
373
387
|
requirements: []
|
374
|
-
rubygems_version: 3.
|
375
|
-
signing_key:
|
388
|
+
rubygems_version: 3.2.7
|
389
|
+
signing_key:
|
376
390
|
specification_version: 4
|
377
391
|
summary: Record your test suite's HTTP interactions and replay them during future
|
378
392
|
test runs for fast, deterministic, accurate tests.
|
@@ -1,103 +0,0 @@
|
|
1
|
-
VCR::VersionChecker.new('Typhoeus', Typhoeus::VERSION, '0.3.2').check_version!
|
2
|
-
|
3
|
-
module VCR
|
4
|
-
class LibraryHooks
|
5
|
-
# @private
|
6
|
-
module Typhoeus
|
7
|
-
# @private
|
8
|
-
class RequestHandler < ::VCR::RequestHandler
|
9
|
-
attr_reader :request
|
10
|
-
def initialize(request)
|
11
|
-
@request = request
|
12
|
-
end
|
13
|
-
|
14
|
-
def vcr_request
|
15
|
-
@vcr_request ||= VCR::Request.new \
|
16
|
-
request.method,
|
17
|
-
request.url,
|
18
|
-
request.body,
|
19
|
-
request.headers
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def externally_stubbed?
|
25
|
-
::Typhoeus::Hydra.stubs.detect { |stub| stub.matches?(request) }
|
26
|
-
end
|
27
|
-
|
28
|
-
def set_typed_request_for_after_hook(*args)
|
29
|
-
super
|
30
|
-
request.instance_variable_set(:@__typed_vcr_request, @after_hook_typed_request)
|
31
|
-
end
|
32
|
-
|
33
|
-
def on_unhandled_request
|
34
|
-
invoke_after_request_hook(nil)
|
35
|
-
super
|
36
|
-
end
|
37
|
-
|
38
|
-
def on_stubbed_by_vcr_request
|
39
|
-
::Typhoeus::Response.new \
|
40
|
-
:http_version => stubbed_response.http_version,
|
41
|
-
:code => stubbed_response.status.code,
|
42
|
-
:status_message => stubbed_response.status.message,
|
43
|
-
:headers_hash => stubbed_response_headers,
|
44
|
-
:body => stubbed_response.body
|
45
|
-
end
|
46
|
-
|
47
|
-
def stubbed_response_headers
|
48
|
-
@stubbed_response_headers ||= {}.tap do |hash|
|
49
|
-
stubbed_response.headers.each do |key, values|
|
50
|
-
hash[key] = values.size == 1 ? values.first : values
|
51
|
-
end if stubbed_response.headers
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
# @private
|
57
|
-
def self.vcr_response_from(response)
|
58
|
-
VCR::Response.new \
|
59
|
-
VCR::ResponseStatus.new(response.code, response.status_message),
|
60
|
-
response.headers_hash,
|
61
|
-
response.body,
|
62
|
-
response.http_version
|
63
|
-
end
|
64
|
-
|
65
|
-
::Typhoeus::Hydra.after_request_before_on_complete do |request|
|
66
|
-
unless VCR.library_hooks.disabled?(:typhoeus)
|
67
|
-
vcr_response = vcr_response_from(request.response)
|
68
|
-
typed_vcr_request = request.send(:remove_instance_variable, :@__typed_vcr_request)
|
69
|
-
|
70
|
-
unless request.response.mock?
|
71
|
-
http_interaction = VCR::HTTPInteraction.new(typed_vcr_request, vcr_response)
|
72
|
-
VCR.record_http_interaction(http_interaction)
|
73
|
-
end
|
74
|
-
|
75
|
-
VCR.configuration.invoke_hook(:after_http_request, typed_vcr_request, vcr_response)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
::Typhoeus::Hydra.register_stub_finder do |request|
|
80
|
-
VCR::LibraryHooks::Typhoeus::RequestHandler.new(request).handle
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
# @private
|
87
|
-
module Typhoeus
|
88
|
-
class << Hydra
|
89
|
-
# ensure HTTP requests are always allowed; VCR takes care of disallowing
|
90
|
-
# them at the appropriate times in its hook
|
91
|
-
def allow_net_connect_with_vcr?(*args)
|
92
|
-
VCR.turned_on? ? true : allow_net_connect_without_vcr?
|
93
|
-
end
|
94
|
-
|
95
|
-
alias allow_net_connect_without_vcr? allow_net_connect?
|
96
|
-
alias allow_net_connect? allow_net_connect_with_vcr?
|
97
|
-
end unless Hydra.respond_to?(:allow_net_connect_with_vcr?)
|
98
|
-
end
|
99
|
-
|
100
|
-
VCR.configuration.after_library_hooks_loaded do
|
101
|
-
::Kernel.warn "WARNING: VCR's Typhoeus 0.4 integration is deprecated and will be removed in VCR 3.0."
|
102
|
-
end
|
103
|
-
|