webmock 3.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gemtest +0 -0
- data/.gitignore +34 -0
- data/.rspec-tm +2 -0
- data/.travis.yml +19 -0
- data/CHANGELOG.md +1698 -0
- data/Gemfile +9 -0
- data/LICENSE +20 -0
- data/README.md +1125 -0
- data/Rakefile +28 -0
- data/lib/webmock.rb +59 -0
- data/lib/webmock/api.rb +109 -0
- data/lib/webmock/assertion_failure.rb +11 -0
- data/lib/webmock/callback_registry.rb +35 -0
- data/lib/webmock/config.rb +18 -0
- data/lib/webmock/cucumber.rb +10 -0
- data/lib/webmock/deprecation.rb +9 -0
- data/lib/webmock/errors.rb +17 -0
- data/lib/webmock/http_lib_adapters/async_http_client_adapter.rb +214 -0
- data/lib/webmock/http_lib_adapters/curb_adapter.rb +347 -0
- data/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +228 -0
- data/lib/webmock/http_lib_adapters/excon_adapter.rb +162 -0
- data/lib/webmock/http_lib_adapters/http_lib_adapter.rb +7 -0
- data/lib/webmock/http_lib_adapters/http_lib_adapter_registry.rb +19 -0
- data/lib/webmock/http_lib_adapters/http_rb/client.rb +14 -0
- data/lib/webmock/http_lib_adapters/http_rb/request.rb +16 -0
- data/lib/webmock/http_lib_adapters/http_rb/response.rb +43 -0
- data/lib/webmock/http_lib_adapters/http_rb/streamer.rb +29 -0
- data/lib/webmock/http_lib_adapters/http_rb/webmock.rb +68 -0
- data/lib/webmock/http_lib_adapters/http_rb_adapter.rb +37 -0
- data/lib/webmock/http_lib_adapters/httpclient_adapter.rb +242 -0
- data/lib/webmock/http_lib_adapters/manticore_adapter.rb +130 -0
- data/lib/webmock/http_lib_adapters/net_http.rb +361 -0
- data/lib/webmock/http_lib_adapters/net_http_response.rb +34 -0
- data/lib/webmock/http_lib_adapters/patron_adapter.rb +130 -0
- data/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +174 -0
- data/lib/webmock/matchers/any_arg_matcher.rb +13 -0
- data/lib/webmock/matchers/hash_argument_matcher.rb +21 -0
- data/lib/webmock/matchers/hash_excluding_matcher.rb +15 -0
- data/lib/webmock/matchers/hash_including_matcher.rb +17 -0
- data/lib/webmock/minitest.rb +41 -0
- data/lib/webmock/rack_response.rb +69 -0
- data/lib/webmock/request_body_diff.rb +64 -0
- data/lib/webmock/request_execution_verifier.rb +77 -0
- data/lib/webmock/request_pattern.rb +370 -0
- data/lib/webmock/request_registry.rb +35 -0
- data/lib/webmock/request_signature.rb +54 -0
- data/lib/webmock/request_signature_snippet.rb +61 -0
- data/lib/webmock/request_stub.rb +100 -0
- data/lib/webmock/response.rb +153 -0
- data/lib/webmock/responses_sequence.rb +40 -0
- data/lib/webmock/rspec.rb +41 -0
- data/lib/webmock/rspec/matchers.rb +27 -0
- data/lib/webmock/rspec/matchers/request_pattern_matcher.rb +78 -0
- data/lib/webmock/rspec/matchers/webmock_matcher.rb +67 -0
- data/lib/webmock/stub_registry.rb +67 -0
- data/lib/webmock/stub_request_snippet.rb +38 -0
- data/lib/webmock/test_unit.rb +22 -0
- data/lib/webmock/util/hash_counter.rb +39 -0
- data/lib/webmock/util/hash_keys_stringifier.rb +25 -0
- data/lib/webmock/util/hash_validator.rb +17 -0
- data/lib/webmock/util/headers.rb +64 -0
- data/lib/webmock/util/json.rb +67 -0
- data/lib/webmock/util/query_mapper.rb +281 -0
- data/lib/webmock/util/uri.rb +110 -0
- data/lib/webmock/util/values_stringifier.rb +20 -0
- data/lib/webmock/util/version_checker.rb +111 -0
- data/lib/webmock/version.rb +3 -0
- data/lib/webmock/webmock.rb +161 -0
- data/minitest/test_helper.rb +34 -0
- data/minitest/test_webmock.rb +9 -0
- data/minitest/webmock_spec.rb +60 -0
- data/spec/acceptance/async_http_client/async_http_client_spec.rb +349 -0
- data/spec/acceptance/async_http_client/async_http_client_spec_helper.rb +73 -0
- data/spec/acceptance/curb/curb_spec.rb +492 -0
- data/spec/acceptance/curb/curb_spec_helper.rb +147 -0
- data/spec/acceptance/em_http_request/em_http_request_spec.rb +406 -0
- data/spec/acceptance/em_http_request/em_http_request_spec_helper.rb +77 -0
- data/spec/acceptance/excon/excon_spec.rb +77 -0
- data/spec/acceptance/excon/excon_spec_helper.rb +50 -0
- data/spec/acceptance/http_rb/http_rb_spec.rb +82 -0
- data/spec/acceptance/http_rb/http_rb_spec_helper.rb +54 -0
- data/spec/acceptance/httpclient/httpclient_spec.rb +217 -0
- data/spec/acceptance/httpclient/httpclient_spec_helper.rb +57 -0
- data/spec/acceptance/manticore/manticore_spec.rb +56 -0
- data/spec/acceptance/manticore/manticore_spec_helper.rb +35 -0
- data/spec/acceptance/net_http/net_http_shared.rb +153 -0
- data/spec/acceptance/net_http/net_http_spec.rb +331 -0
- data/spec/acceptance/net_http/net_http_spec_helper.rb +64 -0
- data/spec/acceptance/net_http/real_net_http_spec.rb +20 -0
- data/spec/acceptance/patron/patron_spec.rb +125 -0
- data/spec/acceptance/patron/patron_spec_helper.rb +54 -0
- data/spec/acceptance/shared/allowing_and_disabling_net_connect.rb +313 -0
- data/spec/acceptance/shared/callbacks.rb +148 -0
- data/spec/acceptance/shared/complex_cross_concern_behaviors.rb +36 -0
- data/spec/acceptance/shared/enabling_and_disabling_webmock.rb +95 -0
- data/spec/acceptance/shared/precedence_of_stubs.rb +15 -0
- data/spec/acceptance/shared/request_expectations.rb +930 -0
- data/spec/acceptance/shared/returning_declared_responses.rb +409 -0
- data/spec/acceptance/shared/stubbing_requests.rb +643 -0
- data/spec/acceptance/typhoeus/typhoeus_hydra_spec.rb +135 -0
- data/spec/acceptance/typhoeus/typhoeus_hydra_spec_helper.rb +60 -0
- data/spec/acceptance/webmock_shared.rb +41 -0
- data/spec/fixtures/test.txt +1 -0
- data/spec/quality_spec.rb +84 -0
- data/spec/spec_helper.rb +48 -0
- data/spec/support/example_curl_output.txt +22 -0
- data/spec/support/failures.rb +9 -0
- data/spec/support/my_rack_app.rb +53 -0
- data/spec/support/network_connection.rb +19 -0
- data/spec/support/webmock_server.rb +70 -0
- data/spec/unit/api_spec.rb +175 -0
- data/spec/unit/errors_spec.rb +129 -0
- data/spec/unit/http_lib_adapters/http_lib_adapter_registry_spec.rb +17 -0
- data/spec/unit/http_lib_adapters/http_lib_adapter_spec.rb +12 -0
- data/spec/unit/matchers/hash_excluding_matcher_spec.rb +61 -0
- data/spec/unit/matchers/hash_including_matcher_spec.rb +87 -0
- data/spec/unit/rack_response_spec.rb +112 -0
- data/spec/unit/request_body_diff_spec.rb +90 -0
- data/spec/unit/request_execution_verifier_spec.rb +208 -0
- data/spec/unit/request_pattern_spec.rb +601 -0
- data/spec/unit/request_registry_spec.rb +95 -0
- data/spec/unit/request_signature_snippet_spec.rb +89 -0
- data/spec/unit/request_signature_spec.rb +155 -0
- data/spec/unit/request_stub_spec.rb +199 -0
- data/spec/unit/response_spec.rb +282 -0
- data/spec/unit/stub_registry_spec.rb +103 -0
- data/spec/unit/stub_request_snippet_spec.rb +115 -0
- data/spec/unit/util/hash_counter_spec.rb +39 -0
- data/spec/unit/util/hash_keys_stringifier_spec.rb +27 -0
- data/spec/unit/util/headers_spec.rb +28 -0
- data/spec/unit/util/json_spec.rb +33 -0
- data/spec/unit/util/query_mapper_spec.rb +157 -0
- data/spec/unit/util/uri_spec.rb +361 -0
- data/spec/unit/util/version_checker_spec.rb +65 -0
- data/spec/unit/webmock_spec.rb +19 -0
- data/test/http_request.rb +24 -0
- data/test/shared_test.rb +108 -0
- data/test/test_helper.rb +23 -0
- data/test/test_webmock.rb +6 -0
- data/webmock.gemspec +45 -0
- metadata +496 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
class WebMock::Util::ValuesStringifier
|
|
2
|
+
def self.stringify_values(value)
|
|
3
|
+
case value
|
|
4
|
+
when String, Numeric, TrueClass, FalseClass
|
|
5
|
+
value.to_s
|
|
6
|
+
when Hash
|
|
7
|
+
Hash[
|
|
8
|
+
value.map do |k, v|
|
|
9
|
+
[k, stringify_values(v)]
|
|
10
|
+
end
|
|
11
|
+
]
|
|
12
|
+
when Array
|
|
13
|
+
value.map do |v|
|
|
14
|
+
stringify_values(v)
|
|
15
|
+
end
|
|
16
|
+
else
|
|
17
|
+
value
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# This code was created based on https://github.com/myronmarston/vcr/blob/master/lib/vcr/util/version_checker.rb
|
|
2
|
+
# Thanks to @myronmarston
|
|
3
|
+
|
|
4
|
+
# Copyright (c) 2010-2012 Myron Marston
|
|
5
|
+
|
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
|
7
|
+
# a copy of this software and associated documentation files (the
|
|
8
|
+
# "Software"), to deal in the Software without restriction, including
|
|
9
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
|
10
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
11
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
|
12
|
+
# the following conditions:
|
|
13
|
+
|
|
14
|
+
# The above copyright notice and this permission notice shall be
|
|
15
|
+
# included in all copies or substantial portions of the Software.
|
|
16
|
+
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
18
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
19
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
20
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
21
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
22
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
23
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
24
|
+
|
|
25
|
+
module WebMock
|
|
26
|
+
class VersionChecker
|
|
27
|
+
def initialize(library_name, library_version, min_patch_level, max_minor_version = nil, unsupported_versions = [])
|
|
28
|
+
@library_name, @library_version = library_name, library_version
|
|
29
|
+
@min_patch_level, @max_minor_version = min_patch_level, max_minor_version
|
|
30
|
+
@unsupported_versions = unsupported_versions || []
|
|
31
|
+
|
|
32
|
+
@major, @minor, @patch = parse_version(library_version)
|
|
33
|
+
@min_major, @min_minor, @min_patch = parse_version(min_patch_level)
|
|
34
|
+
if max_minor_version
|
|
35
|
+
@max_major, @max_minor = parse_version(max_minor_version)
|
|
36
|
+
else
|
|
37
|
+
@max_major, @max_minor = nil, nil
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
@comparison_result = compare_version
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def check_version!
|
|
44
|
+
warn_about_too_low if too_low?
|
|
45
|
+
warn_about_too_high if too_high?
|
|
46
|
+
warn_about_unsupported_version if unsupported_version?
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
def too_low?
|
|
52
|
+
@comparison_result == :too_low
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def too_high?
|
|
56
|
+
@comparison_result == :too_high
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def unsupported_version?
|
|
60
|
+
@unsupported_versions.include?(@library_version)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def warn_about_too_low
|
|
64
|
+
warn_in_red "You are using #{@library_name} #{@library_version}. " +
|
|
65
|
+
"WebMock supports version #{version_requirement}."
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def warn_about_too_high
|
|
69
|
+
warn_in_red "You are using #{@library_name} #{@library_version}. " +
|
|
70
|
+
"WebMock is known to work with #{@library_name} #{version_requirement}. " +
|
|
71
|
+
"It may not work with this version."
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def warn_about_unsupported_version
|
|
75
|
+
warn_in_red "You are using #{@library_name} #{@library_version}. " +
|
|
76
|
+
"WebMock does not support this version. " +
|
|
77
|
+
"WebMock supports versions #{version_requirement}."
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def warn_in_red(text)
|
|
81
|
+
Kernel.warn colorize(text, "\e[31m")
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def compare_version
|
|
85
|
+
case
|
|
86
|
+
when @major < @min_major then :too_low
|
|
87
|
+
when @max_major && @major > @max_major then :too_high
|
|
88
|
+
when @major > @min_major then :ok
|
|
89
|
+
when @minor < @min_minor then :too_low
|
|
90
|
+
when @max_minor && @minor > @max_minor then :too_high
|
|
91
|
+
when @minor > @min_minor then :ok
|
|
92
|
+
when @patch < @min_patch then :too_low
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def version_requirement
|
|
97
|
+
req = ">= #{@min_patch_level}"
|
|
98
|
+
req += ", < #{@max_major}.#{@max_minor + 1}" if @max_minor
|
|
99
|
+
req += ", except versions #{@unsupported_versions.join(',')}" unless @unsupported_versions.empty?
|
|
100
|
+
req
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def parse_version(version)
|
|
104
|
+
version.split('.').map { |v| v.to_i }
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def colorize(text, color_code)
|
|
108
|
+
"#{color_code}#{text}\e[0m"
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
module WebMock
|
|
2
|
+
|
|
3
|
+
def self.included(clazz)
|
|
4
|
+
WebMock::Deprecation.warning("include WebMock is deprecated. Please include WebMock::API instead")
|
|
5
|
+
if clazz.instance_methods.map(&:to_s).include?('request')
|
|
6
|
+
warn "WebMock#request was not included in #{clazz} to avoid name collision"
|
|
7
|
+
else
|
|
8
|
+
clazz.class_eval do
|
|
9
|
+
def request(method, uri)
|
|
10
|
+
WebMock::Deprecation.warning("WebMock#request is deprecated. Please use WebMock::API#a_request method instead")
|
|
11
|
+
WebMock.a_request(method, uri)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
include WebMock::API
|
|
18
|
+
extend WebMock::API
|
|
19
|
+
|
|
20
|
+
class << self
|
|
21
|
+
alias :request :a_request
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.version
|
|
25
|
+
VERSION
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def self.disable!(options = {})
|
|
29
|
+
except = [options[:except]].flatten.compact
|
|
30
|
+
HttpLibAdapterRegistry.instance.each_adapter do |name, adapter|
|
|
31
|
+
adapter.enable!
|
|
32
|
+
adapter.disable! unless except.include?(name)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.enable!(options = {})
|
|
37
|
+
except = [options[:except]].flatten.compact
|
|
38
|
+
HttpLibAdapterRegistry.instance.each_adapter do |name, adapter|
|
|
39
|
+
adapter.disable!
|
|
40
|
+
adapter.enable! unless except.include?(name)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def self.allow_net_connect!(options = {})
|
|
45
|
+
Config.instance.allow_net_connect = true
|
|
46
|
+
Config.instance.net_http_connect_on_start = options[:net_http_connect_on_start]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def self.disable_net_connect!(options = {})
|
|
50
|
+
Config.instance.allow_net_connect = false
|
|
51
|
+
Config.instance.allow_localhost = options[:allow_localhost]
|
|
52
|
+
Config.instance.allow = options[:allow]
|
|
53
|
+
Config.instance.net_http_connect_on_start = options[:net_http_connect_on_start]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
class << self
|
|
57
|
+
alias :enable_net_connect! :allow_net_connect!
|
|
58
|
+
alias :disallow_net_connect! :disable_net_connect!
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def self.net_connect_allowed?(uri = nil)
|
|
62
|
+
if uri.is_a?(String)
|
|
63
|
+
uri = WebMock::Util::URI.normalize_uri(uri)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
Config.instance.allow_net_connect ||
|
|
67
|
+
( Config.instance.allow_localhost && WebMock::Util::URI.is_uri_localhost?(uri) ||
|
|
68
|
+
Config.instance.allow && net_connect_explicit_allowed?(Config.instance.allow, uri) )
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def self.net_connect_explicit_allowed?(allowed, uri=nil)
|
|
72
|
+
case allowed
|
|
73
|
+
when Array
|
|
74
|
+
allowed.any? { |allowed_item| net_connect_explicit_allowed?(allowed_item, uri) }
|
|
75
|
+
when Regexp
|
|
76
|
+
(uri.to_s =~ allowed) != nil ||
|
|
77
|
+
(uri.omit(:port).to_s =~ allowed) != nil && uri.port == uri.default_port
|
|
78
|
+
when String
|
|
79
|
+
allowed == uri.to_s ||
|
|
80
|
+
allowed == uri.host ||
|
|
81
|
+
allowed == "#{uri.host}:#{uri.port}" ||
|
|
82
|
+
allowed == "#{uri.scheme}://#{uri.host}:#{uri.port}" ||
|
|
83
|
+
allowed == "#{uri.scheme}://#{uri.host}" && uri.port == uri.default_port
|
|
84
|
+
else
|
|
85
|
+
if allowed.respond_to?(:call)
|
|
86
|
+
allowed.call(uri)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def self.show_body_diff!
|
|
92
|
+
Config.instance.show_body_diff = true
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def self.hide_body_diff!
|
|
96
|
+
Config.instance.show_body_diff = false
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def self.show_body_diff?
|
|
100
|
+
Config.instance.show_body_diff
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def self.hide_stubbing_instructions!
|
|
104
|
+
Config.instance.show_stubbing_instructions = false
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def self.show_stubbing_instructions!
|
|
108
|
+
Config.instance.show_stubbing_instructions = true
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def self.show_stubbing_instructions?
|
|
112
|
+
Config.instance.show_stubbing_instructions
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def self.reset!
|
|
116
|
+
WebMock::RequestRegistry.instance.reset!
|
|
117
|
+
WebMock::StubRegistry.instance.reset!
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def self.reset_webmock
|
|
121
|
+
WebMock::Deprecation.warning("WebMock.reset_webmock is deprecated. Please use WebMock.reset! method instead")
|
|
122
|
+
reset!
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def self.reset_callbacks
|
|
126
|
+
WebMock::CallbackRegistry.reset
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def self.after_request(options={}, &block)
|
|
130
|
+
WebMock::CallbackRegistry.add_callback(options, block)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def self.registered_request?(request_signature)
|
|
134
|
+
WebMock::StubRegistry.instance.registered_request?(request_signature)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def self.print_executed_requests
|
|
138
|
+
puts WebMock::RequestExecutionVerifier.executed_requests_message
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def self.globally_stub_request(&block)
|
|
142
|
+
WebMock::StubRegistry.instance.register_global_stub(&block)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
%w(
|
|
146
|
+
allow_net_connect!
|
|
147
|
+
disable_net_connect!
|
|
148
|
+
net_connect_allowed?
|
|
149
|
+
reset_webmock
|
|
150
|
+
reset_callbacks
|
|
151
|
+
after_request
|
|
152
|
+
registered_request?
|
|
153
|
+
).each do |method|
|
|
154
|
+
self.class_eval(%Q(
|
|
155
|
+
def #{method}(*args, &block)
|
|
156
|
+
WebMock::Deprecation.warning("WebMock##{method} instance method is deprecated. Please use WebMock.#{method} class method instead")
|
|
157
|
+
WebMock.#{method}(*args, &block)
|
|
158
|
+
end
|
|
159
|
+
))
|
|
160
|
+
end
|
|
161
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
|
|
3
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
4
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
5
|
+
|
|
6
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test/http_request')
|
|
7
|
+
|
|
8
|
+
gem 'minitest'
|
|
9
|
+
|
|
10
|
+
require 'minitest/autorun'
|
|
11
|
+
require 'webmock/minitest'
|
|
12
|
+
|
|
13
|
+
test_class = defined?(MiniTest::Test) ? MiniTest::Test : MiniTest::Unit::TestCase
|
|
14
|
+
|
|
15
|
+
test_class.class_eval do
|
|
16
|
+
|
|
17
|
+
def assert_raise(*exp, &block)
|
|
18
|
+
assert_raises(*exp, &block)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def assert_raise_with_message(e, message, &block)
|
|
22
|
+
e = assert_raises(e, &block)
|
|
23
|
+
if message.is_a?(Regexp)
|
|
24
|
+
assert_match(message, e.message)
|
|
25
|
+
else
|
|
26
|
+
assert_equal(message, e.message)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def assert_fail(message, &block)
|
|
31
|
+
assert_raise_with_message(MiniTest::Assertion, message, &block)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test/shared_test')
|
|
3
|
+
|
|
4
|
+
test_class = defined?(MiniTest::Test) ? MiniTest::Test : MiniTest::Unit::TestCase
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class MiniTestWebMock < test_class
|
|
8
|
+
include SharedTest
|
|
9
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
|
2
|
+
|
|
3
|
+
describe "Webmock" do
|
|
4
|
+
include HttpRequestTestHelper
|
|
5
|
+
|
|
6
|
+
before do
|
|
7
|
+
@stub_http = stub_http_request(:any, "http://www.example.com")
|
|
8
|
+
@stub_https = stub_http_request(:any, "https://www.example.com")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "should update assertions count" do
|
|
12
|
+
assert_equal 0, assertions
|
|
13
|
+
http_request(:get, "http://www.example.com/")
|
|
14
|
+
|
|
15
|
+
assert_requested(@stub_http)
|
|
16
|
+
assert_equal 2, assertions
|
|
17
|
+
|
|
18
|
+
assert_not_requested(:post, "http://www.example.com")
|
|
19
|
+
assert_equal 4, assertions
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "should raise error on non stubbed request" do
|
|
23
|
+
lambda { http_request(:get, "http://www.example.net/") }.must_raise(WebMock::NetConnectNotAllowedError)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "should verify that expected request occured" do
|
|
27
|
+
http_request(:get, "http://www.example.com/")
|
|
28
|
+
assert_requested(:get, "http://www.example.com", times: 1)
|
|
29
|
+
assert_requested(:get, "http://www.example.com")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "should verify that expected http stub occured" do
|
|
33
|
+
http_request(:get, "http://www.example.com/")
|
|
34
|
+
assert_requested(@stub_http, times: 1)
|
|
35
|
+
assert_requested(@stub_http)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "should verify that expected https stub occured" do
|
|
39
|
+
http_request(:get, "https://www.example.com/")
|
|
40
|
+
http_request(:get, "https://www.example.com/")
|
|
41
|
+
assert_requested(@stub_https, times: 2)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "should verify that expect request didn't occur" do
|
|
45
|
+
expected_message = "The request GET http://www.example.com/ was expected to execute 1 time but it executed 0 times"
|
|
46
|
+
expected_message += "\n\nThe following requests were made:\n\nNo requests were made.\n============================================================"
|
|
47
|
+
assert_fail(expected_message) do
|
|
48
|
+
assert_requested(:get, "http://www.example.com")
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "should verify that expect stub didn't occur" do
|
|
53
|
+
expected_message = "The request ANY http://www.example.com/ was expected to execute 1 time but it executed 0 times"
|
|
54
|
+
expected_message += "\n\nThe following requests were made:\n\nNo requests were made.\n============================================================"
|
|
55
|
+
assert_fail(expected_message) do
|
|
56
|
+
assert_requested(@stub_http)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
require 'acceptance/webmock_shared'
|
|
4
|
+
require_relative './async_http_client_spec_helper'
|
|
5
|
+
|
|
6
|
+
require 'protocol/http/body/file'
|
|
7
|
+
|
|
8
|
+
Async.logger.debug! if ENV['ASYNC_LOGGER_DEBUG']
|
|
9
|
+
|
|
10
|
+
unless RUBY_PLATFORM =~ /java/
|
|
11
|
+
describe 'Async::HTTP::Client' do
|
|
12
|
+
include AsyncHttpClientSpecHelper
|
|
13
|
+
|
|
14
|
+
include_context "with WebMock",
|
|
15
|
+
:no_status_message,
|
|
16
|
+
:no_url_auth,
|
|
17
|
+
:no_content_length_header
|
|
18
|
+
|
|
19
|
+
it 'works' do
|
|
20
|
+
stub_request(:get, 'http://www.example.com')
|
|
21
|
+
expect(make_request(:get, 'http://www.example.com')).to eq(
|
|
22
|
+
status: 200,
|
|
23
|
+
headers: {},
|
|
24
|
+
body: nil
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'works with request path' do
|
|
29
|
+
stub_request(:get, 'http://www.example.com/foo')
|
|
30
|
+
expect(make_request(:get, 'http://www.example.com/foo')).to eq(
|
|
31
|
+
status: 200,
|
|
32
|
+
headers: {},
|
|
33
|
+
body: nil
|
|
34
|
+
)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'works with request query' do
|
|
38
|
+
stub_request(:get, 'http://www.example.com/').with(
|
|
39
|
+
query: {
|
|
40
|
+
'foo' => 'bar'
|
|
41
|
+
}
|
|
42
|
+
)
|
|
43
|
+
expect(make_request(:get, 'http://www.example.com/?foo=bar')).to eq(
|
|
44
|
+
status: 200,
|
|
45
|
+
headers: {},
|
|
46
|
+
body: nil
|
|
47
|
+
)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'works with request headers' do
|
|
51
|
+
stub_request(:get, 'http://www.example.com').with(
|
|
52
|
+
headers: {
|
|
53
|
+
'X-Token' => 'Token'
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
expect(
|
|
57
|
+
make_request :get, 'http://www.example.com',
|
|
58
|
+
headers: {
|
|
59
|
+
'X-Token' => 'Token'
|
|
60
|
+
}
|
|
61
|
+
).to eq(
|
|
62
|
+
status: 200,
|
|
63
|
+
headers: {},
|
|
64
|
+
body: nil
|
|
65
|
+
)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'works with request body as text' do
|
|
69
|
+
stub_request(:post, 'http://www.example.com').with(
|
|
70
|
+
body: 'x'*10_000
|
|
71
|
+
)
|
|
72
|
+
expect(
|
|
73
|
+
make_request :post, 'http://www.example.com',
|
|
74
|
+
body: 'x'*10_000
|
|
75
|
+
).to eq(
|
|
76
|
+
status: 200,
|
|
77
|
+
headers: {},
|
|
78
|
+
body: nil
|
|
79
|
+
)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it 'works with request body as file' do
|
|
83
|
+
stub_request(:post, "www.example.com").with(
|
|
84
|
+
body: File.read(__FILE__)
|
|
85
|
+
)
|
|
86
|
+
expect(
|
|
87
|
+
make_request :post, "http://www.example.com",
|
|
88
|
+
body: ::Protocol::HTTP::Body::File.open(__FILE__, block_size: 32)
|
|
89
|
+
).to eq(
|
|
90
|
+
status: 200,
|
|
91
|
+
headers: {},
|
|
92
|
+
body: nil
|
|
93
|
+
)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it 'works with response status' do
|
|
97
|
+
stub_request(:get, 'http://www.example.com').to_return(
|
|
98
|
+
status: 400
|
|
99
|
+
)
|
|
100
|
+
expect(make_request(:get, 'http://www.example.com')).to eq(
|
|
101
|
+
status: 400,
|
|
102
|
+
headers: {},
|
|
103
|
+
body: nil
|
|
104
|
+
)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it 'works with response headers' do
|
|
108
|
+
stub_request(:get, 'http://www.example.com').to_return(
|
|
109
|
+
headers: {
|
|
110
|
+
'X-Token' => 'TOKEN'
|
|
111
|
+
}
|
|
112
|
+
)
|
|
113
|
+
expect(make_request(:get, 'http://www.example.com')).to eq(
|
|
114
|
+
status: 200,
|
|
115
|
+
headers: {
|
|
116
|
+
'x-token' => ['TOKEN']
|
|
117
|
+
},
|
|
118
|
+
body: nil
|
|
119
|
+
)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it 'works with response body' do
|
|
123
|
+
stub_request(:get, 'http://www.example.com').to_return(
|
|
124
|
+
body: 'abc'
|
|
125
|
+
)
|
|
126
|
+
expect(make_request(:get, 'http://www.example.com')).to eq(
|
|
127
|
+
status: 200,
|
|
128
|
+
headers: {},
|
|
129
|
+
body: 'abc'
|
|
130
|
+
)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it 'works with to_timeout' do
|
|
134
|
+
stub_request(:get, 'http://www.example.com').to_timeout
|
|
135
|
+
expect { make_request(:get, 'http://www.example.com') }.to raise_error Async::TimeoutError
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
context 'scheme and protocol' do
|
|
139
|
+
before do
|
|
140
|
+
stub_request(
|
|
141
|
+
:get, "#{scheme}://www.example.com"
|
|
142
|
+
).and_return(
|
|
143
|
+
body: 'BODY'
|
|
144
|
+
)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
subject do
|
|
148
|
+
make_request(:get, "#{scheme}://www.example.com", protocol: protocol)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
shared_examples :common do
|
|
152
|
+
specify do
|
|
153
|
+
expect(subject).to eq(
|
|
154
|
+
status: 200,
|
|
155
|
+
headers: {},
|
|
156
|
+
body: 'BODY'
|
|
157
|
+
)
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
context 'http scheme' do
|
|
162
|
+
let(:scheme) { 'http' }
|
|
163
|
+
|
|
164
|
+
context 'default protocol' do
|
|
165
|
+
let(:protocol) { nil }
|
|
166
|
+
|
|
167
|
+
include_examples :common
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
context 'HTTP10 protocol' do
|
|
171
|
+
let(:protocol) { Async::HTTP::Protocol::HTTP10 }
|
|
172
|
+
|
|
173
|
+
include_examples :common
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
context 'HTTP11 protocol' do
|
|
177
|
+
let(:protocol) { Async::HTTP::Protocol::HTTP11 }
|
|
178
|
+
|
|
179
|
+
include_examples :common
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
context 'HTTP2 protocol' do
|
|
183
|
+
let(:protocol) { Async::HTTP::Protocol::HTTP2 }
|
|
184
|
+
|
|
185
|
+
include_examples :common
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
context 'https scheme' do
|
|
190
|
+
let(:scheme) { 'https' }
|
|
191
|
+
|
|
192
|
+
context 'default protocol' do
|
|
193
|
+
let(:protocol) { nil }
|
|
194
|
+
|
|
195
|
+
include_examples :common
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
context 'HTTP10 protocol' do
|
|
199
|
+
let(:protocol) { Async::HTTP::Protocol::HTTP10 }
|
|
200
|
+
|
|
201
|
+
include_examples :common
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
context 'HTTP11 protocol' do
|
|
205
|
+
let(:protocol) { Async::HTTP::Protocol::HTTP11 }
|
|
206
|
+
|
|
207
|
+
include_examples :common
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
context 'HTTP2 protocol' do
|
|
211
|
+
let(:protocol) { Async::HTTP::Protocol::HTTP2 }
|
|
212
|
+
|
|
213
|
+
include_examples :common
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
context 'HTTPS protocol' do
|
|
217
|
+
let(:protocol) { Async::HTTP::Protocol::HTTPS }
|
|
218
|
+
|
|
219
|
+
include_examples :common
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
context 'multiple requests' do
|
|
225
|
+
let(:endpoint) { Async::HTTP::Endpoint.parse('http://www.example.com') }
|
|
226
|
+
let(:requests_count) { 3 }
|
|
227
|
+
|
|
228
|
+
shared_examples :common do
|
|
229
|
+
before do
|
|
230
|
+
requests_count.times do |index|
|
|
231
|
+
stub_request(
|
|
232
|
+
:get, "http://www.example.com/foo#{index}"
|
|
233
|
+
).to_return(
|
|
234
|
+
status: 200 + index,
|
|
235
|
+
headers: {'X-Token' => "foo#{index}"},
|
|
236
|
+
body: "FOO#{index}"
|
|
237
|
+
)
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
specify do
|
|
242
|
+
expect(subject).to eq(
|
|
243
|
+
0 => {
|
|
244
|
+
status: 200,
|
|
245
|
+
headers: {'x-token' => ['foo0']},
|
|
246
|
+
body: 'FOO0'
|
|
247
|
+
},
|
|
248
|
+
1 => {
|
|
249
|
+
status: 201,
|
|
250
|
+
headers: {'x-token' => ['foo1']},
|
|
251
|
+
body: 'FOO1'
|
|
252
|
+
},
|
|
253
|
+
2 => {
|
|
254
|
+
status: 202,
|
|
255
|
+
headers: {'x-token' => ['foo2']},
|
|
256
|
+
body: 'FOO2'
|
|
257
|
+
}
|
|
258
|
+
)
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
context 'sequential' do
|
|
263
|
+
subject do
|
|
264
|
+
responses = {}
|
|
265
|
+
Async do |task|
|
|
266
|
+
Async::HTTP::Client.open(endpoint, protocol) do |client|
|
|
267
|
+
requests_count.times do |index|
|
|
268
|
+
response = client.get "/foo#{index}"
|
|
269
|
+
responses[index] = response_to_hash(response)
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
responses
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
context 'HTTP1 protocol' do
|
|
277
|
+
let(:protocol) { Async::HTTP::Protocol::HTTP1 }
|
|
278
|
+
|
|
279
|
+
include_examples :common
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
context 'HTTP2 protocol' do
|
|
283
|
+
let(:protocol) { Async::HTTP::Protocol::HTTP2 }
|
|
284
|
+
|
|
285
|
+
include_examples :common
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
context 'asynchronous' do
|
|
290
|
+
subject do
|
|
291
|
+
responses = {}
|
|
292
|
+
Async do |task|
|
|
293
|
+
Async::HTTP::Client.open(endpoint, protocol) do |client|
|
|
294
|
+
tasks = requests_count.times.map do |index|
|
|
295
|
+
task.async do
|
|
296
|
+
response = client.get "/foo#{index}"
|
|
297
|
+
responses[index] = response_to_hash(response)
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
tasks.map(&:wait)
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
responses
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
context 'HTTP1 protocol' do
|
|
308
|
+
let(:protocol) { Async::HTTP::Protocol::HTTP1 }
|
|
309
|
+
|
|
310
|
+
include_examples :common
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
context 'HTTP2 protocol' do
|
|
314
|
+
let(:protocol) { Async::HTTP::Protocol::HTTP2 }
|
|
315
|
+
|
|
316
|
+
include_examples :common
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
def make_request(method, url, protocol: nil, headers: {}, body: nil)
|
|
322
|
+
Async do
|
|
323
|
+
endpoint = Async::HTTP::Endpoint.parse(url)
|
|
324
|
+
|
|
325
|
+
begin
|
|
326
|
+
Async::HTTP::Client.open(endpoint, protocol || endpoint.protocol) do |client|
|
|
327
|
+
response = client.send(
|
|
328
|
+
method,
|
|
329
|
+
endpoint.path,
|
|
330
|
+
headers,
|
|
331
|
+
body
|
|
332
|
+
)
|
|
333
|
+
response_to_hash(response)
|
|
334
|
+
end
|
|
335
|
+
rescue Async::TimeoutError => e
|
|
336
|
+
e
|
|
337
|
+
end
|
|
338
|
+
end.wait
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
def response_to_hash(response)
|
|
342
|
+
{
|
|
343
|
+
status: response.status,
|
|
344
|
+
headers: response.headers.to_h,
|
|
345
|
+
body: response.read
|
|
346
|
+
}
|
|
347
|
+
end
|
|
348
|
+
end
|
|
349
|
+
end
|