webmock 3.14.0 → 3.24.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +207 -3
- data/README.md +65 -20
- data/lib/webmock/api.rb +2 -0
- data/lib/webmock/assertion_failure.rb +2 -0
- data/lib/webmock/callback_registry.rb +2 -0
- data/lib/webmock/config.rb +2 -0
- data/lib/webmock/cucumber.rb +2 -0
- data/lib/webmock/deprecation.rb +2 -0
- data/lib/webmock/errors.rb +2 -0
- data/lib/webmock/http_lib_adapters/async_http_client_adapter.rb +16 -4
- data/lib/webmock/http_lib_adapters/curb_adapter.rb +4 -2
- data/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +17 -7
- data/lib/webmock/http_lib_adapters/excon_adapter.rb +2 -0
- data/lib/webmock/http_lib_adapters/http_lib_adapter.rb +2 -0
- data/lib/webmock/http_lib_adapters/http_lib_adapter_registry.rb +2 -0
- data/lib/webmock/http_lib_adapters/http_rb/client.rb +3 -3
- data/lib/webmock/http_lib_adapters/http_rb/request.rb +17 -5
- data/lib/webmock/http_lib_adapters/http_rb/response.rb +32 -9
- data/lib/webmock/http_lib_adapters/http_rb/streamer.rb +10 -2
- data/lib/webmock/http_lib_adapters/http_rb/webmock.rb +8 -2
- data/lib/webmock/http_lib_adapters/http_rb_adapter.rb +7 -5
- data/lib/webmock/http_lib_adapters/httpclient_adapter.rb +26 -25
- data/lib/webmock/http_lib_adapters/manticore_adapter.rb +2 -0
- data/lib/webmock/http_lib_adapters/net_http.rb +28 -117
- data/lib/webmock/http_lib_adapters/net_http_response.rb +2 -0
- data/lib/webmock/http_lib_adapters/patron_adapter.rb +3 -1
- data/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +18 -2
- data/lib/webmock/matchers/any_arg_matcher.rb +2 -0
- data/lib/webmock/matchers/hash_argument_matcher.rb +2 -0
- data/lib/webmock/matchers/hash_excluding_matcher.rb +2 -0
- data/lib/webmock/matchers/hash_including_matcher.rb +2 -0
- data/lib/webmock/minitest.rb +2 -0
- data/lib/webmock/rack_response.rb +5 -1
- data/lib/webmock/request_body_diff.rb +2 -0
- data/lib/webmock/request_execution_verifier.rb +2 -0
- data/lib/webmock/request_pattern.rb +35 -12
- data/lib/webmock/request_registry.rb +2 -0
- data/lib/webmock/request_signature.rb +4 -2
- data/lib/webmock/request_signature_snippet.rb +2 -0
- data/lib/webmock/request_stub.rb +34 -0
- data/lib/webmock/response.rb +15 -13
- data/lib/webmock/responses_sequence.rb +2 -0
- data/lib/webmock/rspec/matchers/request_pattern_matcher.rb +2 -0
- data/lib/webmock/rspec/matchers/webmock_matcher.rb +2 -0
- data/lib/webmock/rspec/matchers.rb +2 -0
- data/lib/webmock/rspec.rb +2 -0
- data/lib/webmock/stub_registry.rb +2 -0
- data/lib/webmock/stub_request_snippet.rb +2 -0
- data/lib/webmock/test_unit.rb +2 -0
- data/lib/webmock/util/hash_counter.rb +12 -6
- data/lib/webmock/util/hash_keys_stringifier.rb +2 -0
- data/lib/webmock/util/hash_validator.rb +2 -0
- data/lib/webmock/util/headers.rb +23 -10
- data/lib/webmock/util/parsers/json.rb +72 -0
- data/lib/webmock/util/parsers/parse_error.rb +7 -0
- data/lib/webmock/util/parsers/xml.rb +16 -0
- data/lib/webmock/util/query_mapper.rb +2 -0
- data/lib/webmock/util/uri.rb +3 -1
- data/lib/webmock/util/values_stringifier.rb +2 -0
- data/lib/webmock/util/version_checker.rb +7 -5
- data/lib/webmock/version.rb +3 -1
- data/lib/webmock/webmock.rb +12 -0
- data/lib/webmock.rb +4 -2
- metadata +66 -182
- data/.gemtest +0 -0
- data/.github/workflows/CI.yml +0 -37
- data/.gitignore +0 -34
- data/.rspec-tm +0 -2
- data/Gemfile +0 -9
- data/Rakefile +0 -38
- data/lib/webmock/util/json.rb +0 -67
- data/minitest/test_helper.rb +0 -34
- data/minitest/test_webmock.rb +0 -9
- data/minitest/webmock_spec.rb +0 -60
- data/spec/acceptance/async_http_client/async_http_client_spec.rb +0 -375
- data/spec/acceptance/async_http_client/async_http_client_spec_helper.rb +0 -73
- data/spec/acceptance/curb/curb_spec.rb +0 -499
- data/spec/acceptance/curb/curb_spec_helper.rb +0 -147
- data/spec/acceptance/em_http_request/em_http_request_spec.rb +0 -462
- data/spec/acceptance/em_http_request/em_http_request_spec_helper.rb +0 -77
- data/spec/acceptance/excon/excon_spec.rb +0 -77
- data/spec/acceptance/excon/excon_spec_helper.rb +0 -52
- data/spec/acceptance/http_rb/http_rb_spec.rb +0 -93
- data/spec/acceptance/http_rb/http_rb_spec_helper.rb +0 -54
- data/spec/acceptance/httpclient/httpclient_spec.rb +0 -217
- data/spec/acceptance/httpclient/httpclient_spec_helper.rb +0 -57
- data/spec/acceptance/manticore/manticore_spec.rb +0 -107
- data/spec/acceptance/manticore/manticore_spec_helper.rb +0 -35
- data/spec/acceptance/net_http/net_http_shared.rb +0 -153
- data/spec/acceptance/net_http/net_http_spec.rb +0 -369
- data/spec/acceptance/net_http/net_http_spec_helper.rb +0 -64
- data/spec/acceptance/net_http/real_net_http_spec.rb +0 -20
- data/spec/acceptance/patron/patron_spec.rb +0 -125
- data/spec/acceptance/patron/patron_spec_helper.rb +0 -54
- data/spec/acceptance/shared/allowing_and_disabling_net_connect.rb +0 -313
- data/spec/acceptance/shared/callbacks.rb +0 -148
- data/spec/acceptance/shared/complex_cross_concern_behaviors.rb +0 -36
- data/spec/acceptance/shared/enabling_and_disabling_webmock.rb +0 -95
- data/spec/acceptance/shared/precedence_of_stubs.rb +0 -15
- data/spec/acceptance/shared/request_expectations.rb +0 -930
- data/spec/acceptance/shared/returning_declared_responses.rb +0 -409
- data/spec/acceptance/shared/stubbing_requests.rb +0 -678
- data/spec/acceptance/typhoeus/typhoeus_hydra_spec.rb +0 -135
- data/spec/acceptance/typhoeus/typhoeus_hydra_spec_helper.rb +0 -60
- data/spec/acceptance/webmock_shared.rb +0 -41
- data/spec/fixtures/test.txt +0 -1
- data/spec/quality_spec.rb +0 -84
- data/spec/spec_helper.rb +0 -48
- data/spec/support/example_curl_output.txt +0 -22
- data/spec/support/failures.rb +0 -9
- data/spec/support/my_rack_app.rb +0 -53
- data/spec/support/network_connection.rb +0 -19
- data/spec/support/webmock_server.rb +0 -70
- data/spec/unit/api_spec.rb +0 -175
- data/spec/unit/errors_spec.rb +0 -129
- data/spec/unit/http_lib_adapters/http_lib_adapter_registry_spec.rb +0 -17
- data/spec/unit/http_lib_adapters/http_lib_adapter_spec.rb +0 -12
- data/spec/unit/matchers/hash_excluding_matcher_spec.rb +0 -61
- data/spec/unit/matchers/hash_including_matcher_spec.rb +0 -87
- data/spec/unit/rack_response_spec.rb +0 -112
- data/spec/unit/request_body_diff_spec.rb +0 -90
- data/spec/unit/request_execution_verifier_spec.rb +0 -208
- data/spec/unit/request_pattern_spec.rb +0 -736
- data/spec/unit/request_registry_spec.rb +0 -95
- data/spec/unit/request_signature_snippet_spec.rb +0 -89
- data/spec/unit/request_signature_spec.rb +0 -155
- data/spec/unit/request_stub_spec.rb +0 -199
- data/spec/unit/response_spec.rb +0 -286
- data/spec/unit/stub_registry_spec.rb +0 -103
- data/spec/unit/stub_request_snippet_spec.rb +0 -115
- data/spec/unit/util/hash_counter_spec.rb +0 -39
- data/spec/unit/util/hash_keys_stringifier_spec.rb +0 -27
- data/spec/unit/util/headers_spec.rb +0 -28
- data/spec/unit/util/json_spec.rb +0 -33
- data/spec/unit/util/query_mapper_spec.rb +0 -157
- data/spec/unit/util/uri_spec.rb +0 -371
- data/spec/unit/util/version_checker_spec.rb +0 -65
- data/spec/unit/webmock_spec.rb +0 -60
- data/test/http_request.rb +0 -24
- data/test/shared_test.rb +0 -108
- data/test/test_helper.rb +0 -23
- data/test/test_webmock.rb +0 -12
- data/webmock.gemspec +0 -54
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module WebMock
|
2
4
|
|
3
5
|
module RSpecMatcherDetector
|
@@ -82,11 +84,14 @@ module WebMock
|
|
82
84
|
URIAddressablePattern.new(uri)
|
83
85
|
elsif uri.respond_to?(:call)
|
84
86
|
URICallablePattern.new(uri)
|
85
|
-
|
87
|
+
elsif uri.is_a?(::URI::Generic)
|
88
|
+
URIStringPattern.new(uri.to_s)
|
89
|
+
elsif uri.is_a?(String)
|
86
90
|
URIStringPattern.new(uri)
|
91
|
+
else
|
92
|
+
raise ArgumentError.new("URI should be a String, Regexp, Addressable::Template or a callable object. Got: #{uri.class}")
|
87
93
|
end
|
88
94
|
end
|
89
|
-
|
90
95
|
end
|
91
96
|
|
92
97
|
|
@@ -281,7 +286,9 @@ module WebMock
|
|
281
286
|
if (@pattern).is_a?(Hash)
|
282
287
|
return true if @pattern.empty?
|
283
288
|
matching_body_hashes?(body_as_hash(body, content_type), @pattern, content_type)
|
284
|
-
elsif (@pattern).is_a?(
|
289
|
+
elsif (@pattern).is_a?(Array)
|
290
|
+
matching_body_array?(body_as_hash(body, content_type), @pattern, content_type)
|
291
|
+
elsif (@pattern).is_a?(WebMock::Matchers::HashArgumentMatcher)
|
285
292
|
@pattern == body_as_hash(body, content_type)
|
286
293
|
else
|
287
294
|
empty_string?(@pattern) && empty_string?(body) ||
|
@@ -299,12 +306,14 @@ module WebMock
|
|
299
306
|
def body_as_hash(body, content_type)
|
300
307
|
case body_format(content_type)
|
301
308
|
when :json then
|
302
|
-
WebMock::Util::JSON.parse(body)
|
309
|
+
WebMock::Util::Parsers::JSON.parse(body)
|
303
310
|
when :xml then
|
304
|
-
|
311
|
+
WebMock::Util::Parsers::XML.parse(body)
|
305
312
|
else
|
306
313
|
WebMock::Util::QueryMapper.query_to_values(body, notation: Config.instance.query_values_notation)
|
307
314
|
end
|
315
|
+
rescue WebMock::Util::Parsers::ParseError
|
316
|
+
nil
|
308
317
|
end
|
309
318
|
|
310
319
|
def body_format(content_type)
|
@@ -344,19 +353,33 @@ module WebMock
|
|
344
353
|
def matching_body_hashes?(query_parameters, pattern, content_type)
|
345
354
|
return false unless query_parameters.is_a?(Hash)
|
346
355
|
return false unless query_parameters.keys.sort == pattern.keys.sort
|
347
|
-
|
356
|
+
|
357
|
+
query_parameters.all? do |key, actual|
|
348
358
|
expected = pattern[key]
|
359
|
+
matching_values(actual, expected, content_type)
|
360
|
+
end
|
361
|
+
end
|
349
362
|
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
363
|
+
def matching_body_array?(query_parameters, pattern, content_type)
|
364
|
+
return false unless query_parameters.is_a?(Array)
|
365
|
+
return false unless query_parameters.length == pattern.length
|
366
|
+
|
367
|
+
query_parameters.each_with_index do |actual, index|
|
368
|
+
expected = pattern[index]
|
369
|
+
return false unless matching_values(actual, expected, content_type)
|
356
370
|
end
|
371
|
+
|
357
372
|
true
|
358
373
|
end
|
359
374
|
|
375
|
+
def matching_values(actual, expected, content_type)
|
376
|
+
return matching_body_hashes?(actual, expected, content_type) if actual.is_a?(Hash) && expected.is_a?(Hash)
|
377
|
+
return matching_body_array?(actual, expected, content_type) if actual.is_a?(Array) && expected.is_a?(Array)
|
378
|
+
|
379
|
+
expected = WebMock::Util::ValuesStringifier.stringify_values(expected) if url_encoded_body?(content_type)
|
380
|
+
expected === actual
|
381
|
+
end
|
382
|
+
|
360
383
|
def empty_string?(string)
|
361
384
|
string.nil? || string == ""
|
362
385
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module WebMock
|
2
4
|
|
3
5
|
class RequestSignature
|
@@ -35,11 +37,11 @@ module WebMock
|
|
35
37
|
alias == eql?
|
36
38
|
|
37
39
|
def url_encoded?
|
38
|
-
!!(headers
|
40
|
+
!!(headers&.fetch('Content-Type', nil)&.start_with?('application/x-www-form-urlencoded'))
|
39
41
|
end
|
40
42
|
|
41
43
|
def json_headers?
|
42
|
-
!!(headers
|
44
|
+
!!(headers&.fetch('Content-Type', nil)&.start_with?('application/json'))
|
43
45
|
end
|
44
46
|
|
45
47
|
private
|
data/lib/webmock/request_stub.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module WebMock
|
2
4
|
class RequestStub
|
3
5
|
|
@@ -24,6 +26,38 @@ module WebMock
|
|
24
26
|
end
|
25
27
|
alias_method :and_return, :to_return
|
26
28
|
|
29
|
+
def to_return_json(*response_hashes)
|
30
|
+
raise ArgumentError, '#to_return_json does not support passing a block' if block_given?
|
31
|
+
|
32
|
+
json_response_hashes = [*response_hashes].flatten.map do |resp_h|
|
33
|
+
headers, body = resp_h.values_at(:headers, :body)
|
34
|
+
|
35
|
+
json_body = if body.respond_to?(:call)
|
36
|
+
->(request_signature) {
|
37
|
+
b = if body.respond_to?(:arity) && body.arity == 1
|
38
|
+
body.call(request_signature)
|
39
|
+
else
|
40
|
+
body.call
|
41
|
+
end
|
42
|
+
b = b.to_json unless b.is_a?(String)
|
43
|
+
b
|
44
|
+
}
|
45
|
+
elsif !body.is_a?(String)
|
46
|
+
body.to_json
|
47
|
+
else
|
48
|
+
body
|
49
|
+
end
|
50
|
+
|
51
|
+
resp_h.merge(
|
52
|
+
headers: {content_type: 'application/json'}.merge(headers.to_h),
|
53
|
+
body: json_body
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
to_return(json_response_hashes)
|
58
|
+
end
|
59
|
+
alias_method :and_return_json, :to_return_json
|
60
|
+
|
27
61
|
def to_rack(app, options={})
|
28
62
|
@responses_sequences << ResponsesSequence.new([RackResponse.new(app)])
|
29
63
|
end
|
data/lib/webmock/response.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "pathname"
|
2
4
|
|
3
5
|
module WebMock
|
@@ -14,8 +16,11 @@ module WebMock
|
|
14
16
|
|
15
17
|
class Response
|
16
18
|
def initialize(options = {})
|
17
|
-
|
19
|
+
case options
|
20
|
+
when IO, StringIO
|
18
21
|
self.options = read_raw_response(options)
|
22
|
+
when String
|
23
|
+
self.options = read_raw_response(StringIO.new(options))
|
19
24
|
else
|
20
25
|
self.options = options
|
21
26
|
end
|
@@ -33,7 +38,7 @@ module WebMock
|
|
33
38
|
end
|
34
39
|
|
35
40
|
def body
|
36
|
-
@body ||
|
41
|
+
@body || String.new("")
|
37
42
|
end
|
38
43
|
|
39
44
|
def body=(body)
|
@@ -112,21 +117,16 @@ module WebMock
|
|
112
117
|
return if @body.nil?
|
113
118
|
return if valid_types.any? { |c| @body.is_a?(c) }
|
114
119
|
|
115
|
-
if @body.
|
116
|
-
raise InvalidBody, "must be one of: #{valid_types}, but you've used a #{@body.class}
|
117
|
-
"
|
120
|
+
if @body.is_a?(Hash)
|
121
|
+
raise InvalidBody, "must be one of: #{valid_types}, but you've used a #{@body.class}. " \
|
122
|
+
"Please convert it by calling .to_json .to_xml, or otherwise convert it to a string."
|
118
123
|
else
|
119
|
-
raise InvalidBody, "must be one of: #{valid_types}. '#{@body.class}' given"
|
124
|
+
raise InvalidBody, "must be one of: #{valid_types}. '#{@body.class}' given."
|
120
125
|
end
|
121
126
|
end
|
122
127
|
|
123
|
-
def read_raw_response(
|
124
|
-
|
125
|
-
string = raw_response.read
|
126
|
-
raw_response.close
|
127
|
-
raw_response = string
|
128
|
-
end
|
129
|
-
socket = ::Net::BufferedIO.new(raw_response)
|
128
|
+
def read_raw_response(io)
|
129
|
+
socket = ::Net::BufferedIO.new(io)
|
130
130
|
response = ::Net::HTTPResponse.read_new(socket)
|
131
131
|
transfer_encoding = response.delete('transfer-encoding') #chunks were already read by curl
|
132
132
|
response.reading_body(socket, true) {}
|
@@ -138,6 +138,8 @@ module WebMock
|
|
138
138
|
options[:body] = response.read_body
|
139
139
|
options[:status] = [response.code.to_i, response.message]
|
140
140
|
options
|
141
|
+
ensure
|
142
|
+
socket.close
|
141
143
|
end
|
142
144
|
|
143
145
|
InvalidBody = Class.new(StandardError)
|
data/lib/webmock/rspec.rb
CHANGED
data/lib/webmock/test_unit.rb
CHANGED
@@ -1,29 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'thread'
|
2
4
|
|
3
5
|
module WebMock
|
4
6
|
module Util
|
5
7
|
class HashCounter
|
6
8
|
attr_accessor :hash
|
9
|
+
|
7
10
|
def initialize
|
8
|
-
self.hash =
|
11
|
+
self.hash = Hash.new(0)
|
9
12
|
@order = {}
|
10
13
|
@max = 0
|
11
14
|
@lock = ::Mutex.new
|
12
15
|
end
|
13
|
-
|
16
|
+
|
17
|
+
def put(key, num=1)
|
14
18
|
@lock.synchronize do
|
15
|
-
hash[key]
|
16
|
-
@order[key] = @max
|
19
|
+
hash[key] += num
|
20
|
+
@order[key] = @max += 1
|
17
21
|
end
|
18
22
|
end
|
19
|
-
|
23
|
+
|
24
|
+
def get(key)
|
20
25
|
@lock.synchronize do
|
21
|
-
hash[key]
|
26
|
+
hash[key]
|
22
27
|
end
|
23
28
|
end
|
24
29
|
|
25
30
|
def select(&block)
|
26
31
|
return unless block_given?
|
32
|
+
|
27
33
|
@lock.synchronize do
|
28
34
|
hash.select(&block)
|
29
35
|
end
|
data/lib/webmock/util/headers.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module WebMock
|
4
4
|
|
@@ -6,18 +6,21 @@ module WebMock
|
|
6
6
|
|
7
7
|
class Headers
|
8
8
|
|
9
|
+
STANDARD_HEADER_DELIMITER = '-'
|
10
|
+
NONSTANDARD_HEADER_DELIMITER = '_'
|
11
|
+
JOIN = ', '
|
12
|
+
|
9
13
|
def self.normalize_headers(headers)
|
10
14
|
return nil unless headers
|
11
|
-
|
12
|
-
|
13
|
-
|
15
|
+
|
16
|
+
headers.each_with_object({}) do |(name, value), new_headers|
|
17
|
+
new_headers[normalize_name(name)] =
|
18
|
+
case value
|
14
19
|
when Regexp then value
|
15
|
-
when Array then (value.size == 1) ? value.first.to_s : value.map
|
20
|
+
when Array then (value.size == 1) ? value.first.to_s : value.map(&:to_s).sort
|
16
21
|
else value.to_s
|
17
|
-
|
18
|
-
|
19
|
-
}
|
20
|
-
Hash[*array.inject([]) {|r,x| r + x}]
|
22
|
+
end
|
23
|
+
end
|
21
24
|
end
|
22
25
|
|
23
26
|
def self.sorted_headers_string(headers)
|
@@ -54,7 +57,17 @@ module WebMock
|
|
54
57
|
end
|
55
58
|
|
56
59
|
def self.basic_auth_header(*credentials)
|
57
|
-
|
60
|
+
strict_base64_encoded = [credentials.join(':')].pack("m0")
|
61
|
+
"Basic #{strict_base64_encoded.chomp}"
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.normalize_name(name)
|
65
|
+
name
|
66
|
+
.to_s
|
67
|
+
.tr(NONSTANDARD_HEADER_DELIMITER, STANDARD_HEADER_DELIMITER)
|
68
|
+
.split(STANDARD_HEADER_DELIMITER)
|
69
|
+
.map!(&:capitalize)
|
70
|
+
.join(STANDARD_HEADER_DELIMITER)
|
58
71
|
end
|
59
72
|
|
60
73
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This is a copy of https://github.com/jnunemaker/crack/blob/master/lib/crack/json.rb
|
4
|
+
# with date parsing removed
|
5
|
+
# Copyright (c) 2004-2008 David Heinemeier Hansson
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
7
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
8
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
9
|
+
|
10
|
+
require_relative "parse_error"
|
11
|
+
|
12
|
+
module WebMock
|
13
|
+
module Util
|
14
|
+
module Parsers
|
15
|
+
class JSON
|
16
|
+
def self.parse(json)
|
17
|
+
yaml = unescape(convert_json_to_yaml(json))
|
18
|
+
YAML.load(yaml)
|
19
|
+
rescue ArgumentError, Psych::SyntaxError => e
|
20
|
+
raise ParseError, "Invalid JSON string: #{yaml}, Error: #{e.inspect}"
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
|
25
|
+
def self.unescape(str)
|
26
|
+
str.gsub(/\\u([0-9a-f]{4})/) { [$1.hex].pack("U") }
|
27
|
+
end
|
28
|
+
|
29
|
+
# Ensure that ":" and "," are always followed by a space
|
30
|
+
def self.convert_json_to_yaml(json) #:nodoc:
|
31
|
+
scanner, quoting, marks, times = StringScanner.new(json), false, [], []
|
32
|
+
while scanner.scan_until(/(\\['"]|['":,\\]|\\.)/)
|
33
|
+
case char = scanner[1]
|
34
|
+
when '"', "'"
|
35
|
+
if !quoting
|
36
|
+
quoting = char
|
37
|
+
elsif quoting == char
|
38
|
+
quoting = false
|
39
|
+
end
|
40
|
+
when ":",","
|
41
|
+
marks << scanner.pos - 1 unless quoting
|
42
|
+
when "\\"
|
43
|
+
scanner.skip(/\\/)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
if marks.empty?
|
48
|
+
json.gsub(/\\\//, '/')
|
49
|
+
else
|
50
|
+
left_pos = [-1].push(*marks)
|
51
|
+
right_pos = marks << json.bytesize
|
52
|
+
output = []
|
53
|
+
|
54
|
+
left_pos.each_with_index do |left, i|
|
55
|
+
if json.respond_to?(:byteslice)
|
56
|
+
output << json.byteslice(left.succ..right_pos[i])
|
57
|
+
else
|
58
|
+
output << json[left.succ..right_pos[i]]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
output = output * " "
|
63
|
+
|
64
|
+
times.each { |i| output[i-1] = ' ' }
|
65
|
+
output.gsub!(/\\\//, '/')
|
66
|
+
output
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative "parse_error"
|
2
|
+
require "crack/xml"
|
3
|
+
|
4
|
+
module WebMock
|
5
|
+
module Util
|
6
|
+
module Parsers
|
7
|
+
class XML
|
8
|
+
def self.parse(xml)
|
9
|
+
::Crack::XML.parse(xml)
|
10
|
+
rescue ::REXML::ParseException => e
|
11
|
+
raise ParseError, "Invalid XML string: #{xml}, Error: #{e.inspect}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/webmock/util/uri.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module WebMock
|
2
4
|
|
3
5
|
module Util
|
@@ -68,7 +70,7 @@ module WebMock
|
|
68
70
|
|
69
71
|
def self.is_uri_localhost?(uri)
|
70
72
|
uri.is_a?(Addressable::URI) &&
|
71
|
-
%w(localhost 127.0.0.1 0.0.0.0).include?(uri.host)
|
73
|
+
%w(localhost 127.0.0.1 0.0.0.0 [::1]).include?(uri.host)
|
72
74
|
end
|
73
75
|
|
74
76
|
private
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This code was created based on https://github.com/myronmarston/vcr/blob/master/lib/vcr/util/version_checker.rb
|
2
4
|
# Thanks to @myronmarston
|
3
5
|
|
@@ -84,12 +86,12 @@ module WebMock
|
|
84
86
|
def compare_version
|
85
87
|
case
|
86
88
|
when @major < @min_major then :too_low
|
89
|
+
when @major == @min_major && @minor < @min_minor then :too_low
|
90
|
+
when @major == @min_major && @minor == @min_minor && @patch < @min_patch then :too_low
|
87
91
|
when @max_major && @major > @max_major then :too_high
|
88
|
-
when @major > @
|
89
|
-
|
90
|
-
|
91
|
-
when @minor > @min_minor then :ok
|
92
|
-
when @patch < @min_patch then :too_low
|
92
|
+
when @max_major && @major == @max_major && @max_minor && @minor > @max_minor then :too_high
|
93
|
+
|
94
|
+
else :ok
|
93
95
|
end
|
94
96
|
end
|
95
97
|
|
data/lib/webmock/version.rb
CHANGED
data/lib/webmock/webmock.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module WebMock
|
2
4
|
|
3
5
|
def self.included(clazz)
|
@@ -70,6 +72,16 @@ module WebMock
|
|
70
72
|
Config.instance.allow && net_connect_explicit_allowed?(Config.instance.allow, uri) )
|
71
73
|
end
|
72
74
|
|
75
|
+
def self.net_http_connect_on_start?(uri)
|
76
|
+
allowed = Config.instance.net_http_connect_on_start || false
|
77
|
+
|
78
|
+
if [true, false].include?(allowed)
|
79
|
+
allowed
|
80
|
+
else
|
81
|
+
net_connect_explicit_allowed?(allowed, uri)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
73
85
|
def self.net_connect_explicit_allowed?(allowed, uri=nil)
|
74
86
|
case allowed
|
75
87
|
when Array
|
data/lib/webmock.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'singleton'
|
2
4
|
|
3
5
|
require 'addressable/uri'
|
4
6
|
require 'addressable/template'
|
5
|
-
require 'crack/xml'
|
6
7
|
|
7
8
|
require_relative 'webmock/deprecation'
|
8
9
|
require_relative 'webmock/version'
|
@@ -15,7 +16,8 @@ require_relative 'webmock/util/headers'
|
|
15
16
|
require_relative 'webmock/util/hash_counter'
|
16
17
|
require_relative 'webmock/util/hash_keys_stringifier'
|
17
18
|
require_relative 'webmock/util/values_stringifier'
|
18
|
-
require_relative 'webmock/util/json'
|
19
|
+
require_relative 'webmock/util/parsers/json'
|
20
|
+
require_relative 'webmock/util/parsers/xml'
|
19
21
|
require_relative 'webmock/util/version_checker'
|
20
22
|
require_relative 'webmock/util/hash_validator'
|
21
23
|
|