webmock 0.7.1 → 0.7.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +9 -0
- data/README.md +169 -76
- data/Rakefile +2 -1
- data/VERSION +1 -1
- data/lib/webmock.rb +12 -9
- data/lib/webmock/adapters/rspec.rb +20 -22
- data/lib/webmock/adapters/rspec/matchers.rb +4 -4
- data/lib/webmock/adapters/rspec/webmock_matcher.rb +2 -2
- data/lib/webmock/adapters/test_unit.rb +20 -21
- data/lib/webmock/http_lib_adapters/net_http.rb +51 -15
- data/lib/webmock/request_profile.rb +5 -44
- data/lib/webmock/request_registry.rb +10 -11
- data/lib/webmock/request_signature.rb +44 -0
- data/lib/webmock/request_stub.rb +3 -3
- data/lib/webmock/response.rb +1 -1
- data/lib/webmock/rspec.rb +1 -0
- data/lib/webmock/test_unit.rb +1 -0
- data/lib/webmock/util/hash_counter.rb +16 -8
- data/lib/webmock/util/headers.rb +23 -0
- data/lib/webmock/util/uri.rb +81 -0
- data/lib/webmock/webmock.rb +16 -19
- data/spec/net_http_spec.rb +10 -9
- data/spec/other_net_http_libs_spec.rb +3 -1
- data/spec/request_profile_spec.rb +6 -116
- data/spec/request_registry_spec.rb +12 -17
- data/spec/request_signature_spec.rb +155 -0
- data/spec/request_stub_spec.rb +2 -2
- data/spec/response_spec.rb +1 -1
- data/spec/spec_helper.rb +4 -1
- data/spec/util/hash_counter_spec.rb +4 -4
- data/spec/util/headers_spec.rb +11 -0
- data/spec/util/uri_spec.rb +213 -0
- data/spec/vendor/addressable/lib/addressable/uri.rb +8 -0
- data/spec/vendor/addressable/lib/uri.rb +0 -0
- data/spec/webmock_spec.rb +58 -10
- data/test/test_helper.rb +5 -1
- data/test/test_webmock.rb +11 -6
- data/webmock.gemspec +21 -6
- metadata +28 -6
- data/lib/webmock/url.rb +0 -46
- data/lib/webmock/utility.rb +0 -65
- data/spec/utility_spec.rb +0 -70
@@ -8,12 +8,12 @@ module WebMock
|
|
8
8
|
WebMock::RequestProfileMatcher.new.times(0)
|
9
9
|
end
|
10
10
|
|
11
|
-
def have_requested(method,
|
12
|
-
WebMock::WebMockMatcher.new(method,
|
11
|
+
def have_requested(method, uri)
|
12
|
+
WebMock::WebMockMatcher.new(method, uri)
|
13
13
|
end
|
14
14
|
|
15
|
-
def have_not_requested(method,
|
16
|
-
WebMock::WebMockMatcher.new(method,
|
15
|
+
def have_not_requested(method, uri)
|
16
|
+
WebMock::WebMockMatcher.new(method, uri).times(0)
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
module WebMock
|
2
2
|
class WebMockMatcher
|
3
3
|
|
4
|
-
def initialize(method,
|
4
|
+
def initialize(method, uri)
|
5
5
|
@request_execution_verifier = RequestExecutionVerifier.new
|
6
|
-
@request_execution_verifier.request_profile = RequestProfile.new(method,
|
6
|
+
@request_execution_verifier.request_profile = RequestProfile.new(method, uri)
|
7
7
|
end
|
8
8
|
|
9
9
|
def once
|
@@ -1,25 +1,24 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
class Test::Unit::TestCase
|
4
|
-
include WebMock
|
5
|
-
alias setup_without_webmock setup
|
6
|
-
def setup
|
7
|
-
reset_webmock
|
8
|
-
@original_allow_net_connect = WebMock.net_connect_allowed?
|
9
|
-
WebMock.disable_net_connect!
|
10
|
-
end
|
1
|
+
require 'test/unit'
|
2
|
+
require 'webmock'
|
11
3
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
4
|
+
class Test::Unit::TestCase
|
5
|
+
alias setup_without_webmock setup
|
6
|
+
def setup
|
7
|
+
WebMock.reset_webmock
|
8
|
+
@original_allow_net_connect = WebMock.net_connect_allowed?
|
9
|
+
WebMock.disable_net_connect!
|
16
10
|
end
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
raise Test::Unit::AssertionFailedError.new(message)
|
22
|
-
end
|
11
|
+
|
12
|
+
alias teardown_without_webmock teardown
|
13
|
+
def teardown
|
14
|
+
@original_allow_net_connect ? WebMock.allow_net_connect! : WebMock.disable_net_connect!
|
23
15
|
end
|
24
|
-
|
25
16
|
end
|
17
|
+
|
18
|
+
module WebMock
|
19
|
+
private
|
20
|
+
def assertion_failure(message)
|
21
|
+
raise Test::Unit::AssertionFailedError.new(message)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
@@ -2,7 +2,6 @@ require 'net/http'
|
|
2
2
|
require 'net/https'
|
3
3
|
require 'stringio'
|
4
4
|
|
5
|
-
|
6
5
|
class StubSocket #:nodoc:
|
7
6
|
|
8
7
|
def initialize(*args)
|
@@ -61,11 +60,11 @@ module Net #:nodoc: all
|
|
61
60
|
protocol = use_ssl? ? "https" : "http"
|
62
61
|
|
63
62
|
path = request.path
|
64
|
-
path = URI.
|
63
|
+
path = Addressable::URI.heuristic_parse(request.path).request_uri if request.path =~ /^http/
|
65
64
|
|
66
65
|
if request["authorization"] =~ /^Basic /
|
67
|
-
userinfo = WebMock::
|
68
|
-
userinfo = WebMock::
|
66
|
+
userinfo = WebMock::Util::Headers.decode_userinfo_from_header(request["authorization"])
|
67
|
+
userinfo = WebMock::Util::URI.encode_unsafe_chars_in_userinfo(userinfo) + "@"
|
69
68
|
else
|
70
69
|
userinfo = ""
|
71
70
|
end
|
@@ -74,24 +73,21 @@ module Net #:nodoc: all
|
|
74
73
|
method = request.method.downcase.to_sym
|
75
74
|
|
76
75
|
headers = Hash[*request.to_hash.map {|k,v| [k, v.flatten]}.flatten]
|
77
|
-
headers.reject! {|k,v| k =~ /[Aa]ccept/ && v = '*/*'}
|
76
|
+
headers.reject! {|k,v| k =~ /[Aa]ccept/ && v = '*/*'} #removing header added by Net::HTTP
|
77
|
+
|
78
|
+
request_signature = WebMock::RequestSignature.new(method, uri, body, headers)
|
78
79
|
|
79
|
-
|
80
|
+
WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)
|
80
81
|
|
81
|
-
if WebMock.registered_request?(
|
82
|
+
if WebMock.registered_request?(request_signature)
|
82
83
|
@socket = Net::HTTP.socket_type.new
|
83
|
-
webmock_response = WebMock.response_for_request(
|
84
|
+
webmock_response = WebMock.response_for_request(request_signature)
|
84
85
|
build_net_http_response(webmock_response, &block)
|
85
86
|
elsif WebMock.net_connect_allowed?
|
86
|
-
WebMock::RequestRegistry.instance.requested.put(request_profile)
|
87
87
|
connect_without_webmock
|
88
88
|
request_without_webmock(request, body, &block)
|
89
89
|
else
|
90
|
-
|
91
|
-
message = "Real HTTP connections are disabled. Unregistered request: #{request.method} #{uri}"
|
92
|
-
message << " with body '#{body}'" if body
|
93
|
-
message << " with headers #{WebMock::Utility.normalize_headers(headers).inspect.gsub("\"","'")}" if
|
94
|
-
headers && !headers.empty?
|
90
|
+
message = "Real HTTP connections are disabled. Unregistered request: #{request_signature}"
|
95
91
|
raise WebMock::NetConnectNotAllowedError, message
|
96
92
|
end
|
97
93
|
end
|
@@ -101,7 +97,7 @@ headers && !headers.empty?
|
|
101
97
|
|
102
98
|
def connect_with_webmock
|
103
99
|
unless @@alredy_checked_for_net_http_replacement_libs ||= false
|
104
|
-
WebMock::
|
100
|
+
WebMock::NetHTTPUtility.puts_warning_for_net_http_replacement_libs_if_needed
|
105
101
|
@@alredy_checked_for_net_http_replacement_libs = true
|
106
102
|
end
|
107
103
|
nil
|
@@ -127,3 +123,43 @@ headers && !headers.empty?
|
|
127
123
|
end
|
128
124
|
|
129
125
|
end
|
126
|
+
|
127
|
+
module WebMock
|
128
|
+
module NetHTTPUtility
|
129
|
+
def self.puts_warning_for_net_http_around_advice_libs_if_needed
|
130
|
+
libs = {"Samuel" => defined?(Samuel)}
|
131
|
+
warnings = libs.select { |_, loaded| loaded }.map do |name, _|
|
132
|
+
<<-TEXT.gsub(/ {10}/, '')
|
133
|
+
\e[1mWarning: WebMock was loaded after #{name}\e[0m
|
134
|
+
* #{name}'s code is being ignored when a request is handled by WebMock,
|
135
|
+
because both libraries work by patching Net::HTTP.
|
136
|
+
* To fix this, just reorder your requires so that WebMock is before #{name}.
|
137
|
+
TEXT
|
138
|
+
end
|
139
|
+
$stderr.puts "\n" + warnings.join("\n") + "\n" if warnings.any?
|
140
|
+
end
|
141
|
+
|
142
|
+
def self.record_loaded_net_http_replacement_libs
|
143
|
+
libs = {"RightHttpConnection" => defined?(RightHttpConnection)}
|
144
|
+
@loaded_net_http_replacement_libs = libs.map { |name, loaded| name if loaded }.compact
|
145
|
+
end
|
146
|
+
|
147
|
+
def self.puts_warning_for_net_http_replacement_libs_if_needed
|
148
|
+
libs = {"RightHttpConnection" => defined?(RightHttpConnection)}
|
149
|
+
warnings = libs.select { |_, loaded| loaded }.
|
150
|
+
reject { |name, _| @loaded_net_http_replacement_libs.include?(name) }.
|
151
|
+
map do |name, _|
|
152
|
+
<<-TEXT.gsub(/ {10}/, '')
|
153
|
+
\e[1mWarning: #{name} was loaded after WebMock\e[0m
|
154
|
+
* WebMock's code is being ignored, because #{name} replaces parts of
|
155
|
+
Net::HTTP without deferring to other libraries. This will break Net::HTTP requests.
|
156
|
+
* To fix this, just reorder your requires so that #{name} is before WebMock.
|
157
|
+
TEXT
|
158
|
+
end
|
159
|
+
$stderr.puts "\n" + warnings.join("\n") + "\n" if warnings.any?
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
WebMock::NetHTTPUtility.record_loaded_net_http_replacement_libs
|
165
|
+
WebMock::NetHTTPUtility.puts_warning_for_net_http_around_advice_libs_if_needed
|
@@ -4,64 +4,25 @@ module WebMock
|
|
4
4
|
|
5
5
|
def initialize(method, uri, body = nil, headers = nil)
|
6
6
|
super
|
7
|
-
self.uri = WebMock::
|
8
|
-
self.headers =
|
7
|
+
self.uri = WebMock::Util::URI.normalize_uri(self.uri) unless self.uri.is_a?(Addressable::URI)
|
8
|
+
self.headers = WebMock::Util::Headers.normalize_headers(self.headers)
|
9
9
|
end
|
10
10
|
|
11
11
|
def with(options)
|
12
12
|
self.body = options[:body] if options.has_key?(:body)
|
13
|
-
self.headers =
|
13
|
+
self.headers = WebMock::Util::Headers.normalize_headers(options[:headers]) if options.has_key?(:headers)
|
14
14
|
self
|
15
15
|
end
|
16
16
|
|
17
|
-
#self needs to be a subset of other. Other needs to be more general.
|
18
|
-
def match(other)
|
19
|
-
match_method(other) &&
|
20
|
-
match_body(other) &&
|
21
|
-
match_headers(other) &&
|
22
|
-
match_url(other)
|
23
|
-
end
|
24
|
-
|
25
17
|
def to_s
|
26
|
-
string = "#{self.method.to_s.upcase} #{self.uri}"
|
18
|
+
string = "#{self.method.to_s.upcase} #{WebMock::Util::URI.strip_default_port_from_uri_string(self.uri.to_s)}"
|
27
19
|
string << " with body '#{body}'" if body
|
28
20
|
if headers && !headers.empty?
|
29
|
-
string << " with headers #{WebMock::
|
21
|
+
string << " with headers #{WebMock::Util::Headers.normalize_headers(headers).inspect.gsub("\"","'")}"
|
30
22
|
end
|
31
23
|
string
|
32
24
|
end
|
33
25
|
|
34
|
-
private
|
35
|
-
|
36
|
-
def match_url(other)
|
37
|
-
raise "Can't match regexp request profile" if self.uri.is_a?(Regexp)
|
38
|
-
@uris_to_check ||= WebMock::URL.variations_of_uri_as_strings(self.uri)
|
39
|
-
if other.uri.is_a?(URI)
|
40
|
-
@uris_to_check.include?(other.uri.to_s)
|
41
|
-
elsif other.uri.is_a?(Regexp)
|
42
|
-
@uris_to_check.any? { |u| u.match(other.uri) }
|
43
|
-
else
|
44
|
-
false
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def match_headers(other)
|
49
|
-
return false if self.headers && !self.headers.empty? && other.headers && other.headers.empty?
|
50
|
-
if other.headers && !other.headers.empty?
|
51
|
-
other.headers.each do | key, value |
|
52
|
-
return false unless (self.headers && self.headers.has_key?(key) && value == self.headers[key])
|
53
|
-
end
|
54
|
-
end
|
55
|
-
return true
|
56
|
-
end
|
57
|
-
|
58
|
-
def match_body(other)
|
59
|
-
other.body == self.body || other.body.nil?
|
60
|
-
end
|
61
|
-
|
62
|
-
def match_method(other)
|
63
|
-
other.method == self.method || other.method == :any
|
64
|
-
end
|
65
26
|
end
|
66
27
|
|
67
28
|
end
|
@@ -3,7 +3,7 @@ module WebMock
|
|
3
3
|
class RequestRegistry
|
4
4
|
include Singleton
|
5
5
|
|
6
|
-
attr_accessor :request_stubs, :
|
6
|
+
attr_accessor :request_stubs, :requested_signatures
|
7
7
|
|
8
8
|
def initialize
|
9
9
|
reset_webmock
|
@@ -11,7 +11,7 @@ module WebMock
|
|
11
11
|
|
12
12
|
def reset_webmock
|
13
13
|
self.request_stubs = []
|
14
|
-
self.
|
14
|
+
self.requested_signatures = Util::HashCounter.new
|
15
15
|
end
|
16
16
|
|
17
17
|
def register_request_stub(stub)
|
@@ -19,27 +19,26 @@ module WebMock
|
|
19
19
|
stub
|
20
20
|
end
|
21
21
|
|
22
|
-
def registered_request?(
|
23
|
-
|
22
|
+
def registered_request?(request_signature)
|
23
|
+
request_stub_for(request_signature)
|
24
24
|
end
|
25
25
|
|
26
|
-
def response_for_request(
|
27
|
-
stub =
|
28
|
-
self.requested.put(request_profile)
|
26
|
+
def response_for_request(request_signature)
|
27
|
+
stub = request_stub_for(request_signature)
|
29
28
|
stub ? stub.response : nil
|
30
29
|
end
|
31
30
|
|
32
31
|
def times_executed(request_profile)
|
33
|
-
self.
|
34
|
-
|
32
|
+
self.requested_signatures.hash.select { |request_signature, times_executed|
|
33
|
+
request_signature.match(request_profile)
|
35
34
|
}.inject(0) {|sum, (_, times_executed)| sum + times_executed }
|
36
35
|
end
|
37
36
|
|
38
37
|
private
|
39
38
|
|
40
|
-
def
|
39
|
+
def request_stub_for(request_signature)
|
41
40
|
request_stubs.detect { |registered_request_stub|
|
42
|
-
|
41
|
+
request_signature.match(registered_request_stub.request_profile)
|
43
42
|
}
|
44
43
|
end
|
45
44
|
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module WebMock
|
2
|
+
|
3
|
+
class RequestSignature < RequestProfile
|
4
|
+
|
5
|
+
def match(request_profile)
|
6
|
+
match_method(request_profile) &&
|
7
|
+
match_body(request_profile) &&
|
8
|
+
match_headers(request_profile) &&
|
9
|
+
match_uri(request_profile)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def match_uri(request_profile)
|
15
|
+
if request_profile.uri.is_a?(Addressable::URI)
|
16
|
+
WebMock::Util::URI.normalize_uri(uri) === WebMock::Util::URI.normalize_uri(request_profile.uri)
|
17
|
+
elsif request_profile.uri.is_a?(Regexp)
|
18
|
+
WebMock::Util::URI.variations_of_uri_as_strings(self.uri).any? { |u| u.match(request_profile.uri) }
|
19
|
+
else
|
20
|
+
false
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def match_headers(request_profile)
|
25
|
+
return false if self.headers && !self.headers.empty? && request_profile.headers && request_profile.headers.empty?
|
26
|
+
if request_profile.headers && !request_profile.headers.empty?
|
27
|
+
request_profile.headers.each do | key, value |
|
28
|
+
return false unless (self.headers && self.headers.has_key?(key) && value == self.headers[key])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
return true
|
32
|
+
end
|
33
|
+
|
34
|
+
def match_body(request_profile)
|
35
|
+
request_profile.body == self.body || request_profile.body.nil?
|
36
|
+
end
|
37
|
+
|
38
|
+
def match_method(request_profile)
|
39
|
+
request_profile.method == self.method || request_profile.method == :any
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
end
|
data/lib/webmock/request_stub.rb
CHANGED
@@ -2,15 +2,15 @@ module WebMock
|
|
2
2
|
class RequestStub
|
3
3
|
attr_accessor :request_profile, :response
|
4
4
|
|
5
|
-
def initialize(method,
|
6
|
-
@request_profile = RequestProfile.new(method,
|
5
|
+
def initialize(method, uri)
|
6
|
+
@request_profile = RequestProfile.new(method, uri)
|
7
7
|
@response = WebMock::Response.new
|
8
8
|
self
|
9
9
|
end
|
10
10
|
|
11
11
|
def with(params)
|
12
12
|
@request_profile.body = params[:body]
|
13
|
-
@request_profile.headers =
|
13
|
+
@request_profile.headers = Util::Headers.normalize_headers(params[:headers])
|
14
14
|
self
|
15
15
|
end
|
16
16
|
|
data/lib/webmock/response.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "adapters/rspec")
|
@@ -0,0 +1 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "adapters/test_unit")
|
@@ -1,12 +1,20 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
module WebMock
|
2
|
+
|
3
|
+
module Util
|
4
|
+
|
5
|
+
class Util::HashCounter
|
6
|
+
attr_accessor :hash
|
7
|
+
def initialize
|
4
8
|
self.hash = {}
|
5
|
-
|
6
|
-
|
9
|
+
end
|
10
|
+
def put key, num=1
|
7
11
|
hash[key] = (hash[key] || 0) + num
|
8
|
-
|
9
|
-
|
12
|
+
end
|
13
|
+
def get key
|
10
14
|
hash[key] || 0
|
15
|
+
end
|
11
16
|
end
|
12
|
-
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module WebMock
|
2
|
+
|
3
|
+
module Util
|
4
|
+
|
5
|
+
class Headers
|
6
|
+
|
7
|
+
def self.normalize_headers(headers)
|
8
|
+
return nil unless headers
|
9
|
+
array = headers.map { |name, value|
|
10
|
+
[name.to_s.split(/_|-/).map { |segment| segment.capitalize }.join("-"), value.to_s]
|
11
|
+
}
|
12
|
+
Hash[*array.flatten]
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.decode_userinfo_from_header(header)
|
16
|
+
header.sub(/^Basic /, "").unpack("m").first
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Addressable
|
2
|
+
class URI
|
3
|
+
module CharacterClasses
|
4
|
+
USERINFO = UNRESERVED + SUB_DELIMS + "\\:"
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
module WebMock
|
10
|
+
|
11
|
+
module Util
|
12
|
+
|
13
|
+
class URI
|
14
|
+
|
15
|
+
def self.normalize_uri(uri)
|
16
|
+
return uri if uri.is_a?(Regexp)
|
17
|
+
uri = 'http://' + uri unless uri.match('^https?://') if uri.is_a?(String)
|
18
|
+
normalized_uri = Addressable::URI.heuristic_parse(uri)
|
19
|
+
normalized_uri.query_values = normalized_uri.query_values if normalized_uri.query_values
|
20
|
+
normalized_uri.normalize!
|
21
|
+
normalized_uri.port = normalized_uri.inferred_port unless normalized_uri.port && normalized_uri.inferred_port
|
22
|
+
normalized_uri
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.variations_of_uri_as_strings(uri_object)
|
26
|
+
normalized_uri = normalize_uri(uri_object.dup).freeze
|
27
|
+
uris = [ normalized_uri ]
|
28
|
+
|
29
|
+
if normalized_uri.port == Addressable::URI.port_mapping[normalized_uri.scheme]
|
30
|
+
uris = uris_with_inferred_port_and_without(uris)
|
31
|
+
end
|
32
|
+
|
33
|
+
if normalized_uri.scheme == "http"
|
34
|
+
uris = uris_with_scheme_and_without(uris)
|
35
|
+
end
|
36
|
+
|
37
|
+
if normalized_uri.path == '/' && normalized_uri.query == nil
|
38
|
+
uris = uris_with_trailing_slash_and_without(uris)
|
39
|
+
end
|
40
|
+
|
41
|
+
uris = uris_encoded_and_unencoded(uris)
|
42
|
+
|
43
|
+
uris.map {|uri| uri.to_s.gsub(/^\/\//,'') }.uniq
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.strip_default_port_from_uri_string(uri_string)
|
47
|
+
case uri_string
|
48
|
+
when %r{^http://} then uri_string.sub(%r{:80(/|$)}, '\1')
|
49
|
+
when %r{^https://} then uri_string.sub(%r{:443(/|$)}, '\1')
|
50
|
+
else uri_string
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.encode_unsafe_chars_in_userinfo(userinfo)
|
55
|
+
Addressable::URI.encode_component(userinfo, Addressable::URI::CharacterClasses::USERINFO)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def self.uris_with_inferred_port_and_without(uris)
|
61
|
+
uris.map { |uri| [ uri, uri.omit(:port).freeze ] }.flatten
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.uris_encoded_and_unencoded(uris)
|
65
|
+
uris.map do |uri|
|
66
|
+
[ uri, Addressable::URI.heuristic_parse(Addressable::URI.unencode(uri)).freeze ]
|
67
|
+
end.flatten
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.uris_with_scheme_and_without(uris)
|
71
|
+
uris.map { |uri| [ uri, uri.omit(:scheme).freeze ] }.flatten
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.uris_with_trailing_slash_and_without(uris)
|
75
|
+
uris = uris.map { |uri| [ uri, uri.omit(:path).freeze ] }.flatten
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|