typhoeus 0.6.2 → 0.6.3
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.
- data/CHANGELOG.md +13 -1
- data/Gemfile +1 -1
- data/README.md +3 -3
- data/lib/typhoeus.rb +18 -16
- data/lib/typhoeus/adapters/faraday.rb +14 -0
- data/lib/typhoeus/config.rb +6 -6
- data/lib/typhoeus/errors.rb +1 -1
- data/lib/typhoeus/expectation.rb +55 -18
- data/lib/typhoeus/hydra.rb +1 -1
- data/lib/typhoeus/hydra/stubbable.rb +2 -2
- data/lib/typhoeus/pool.rb +3 -3
- data/lib/typhoeus/request.rb +4 -4
- data/lib/typhoeus/request/stubbable.rb +2 -2
- data/lib/typhoeus/response.rb +4 -4
- data/lib/typhoeus/response/informations.rb +1 -1
- data/lib/typhoeus/version.rb +1 -1
- metadata +5 -5
data/CHANGELOG.md
CHANGED
@@ -2,7 +2,19 @@
|
|
2
2
|
|
3
3
|
## Master
|
4
4
|
|
5
|
-
[Full Changelog](http://github.com/typhoeus/typhoeus/compare/v0.6.
|
5
|
+
[Full Changelog](http://github.com/typhoeus/typhoeus/compare/v0.6.3...master)
|
6
|
+
|
7
|
+
## 0.6.3
|
8
|
+
|
9
|
+
[Full Changelog](http://github.com/typhoeus/typhoeus/compare/v0.6.2...v0.6.3)
|
10
|
+
|
11
|
+
Enhancements:
|
12
|
+
|
13
|
+
* Cache hydra per thread.
|
14
|
+
* Various documentation improvements.
|
15
|
+
([craiglittle](https://github.com/craiglittle))
|
16
|
+
* Add support for lazy construction of responses from stubbed requests.
|
17
|
+
([ryankindermann](https://github.com/ryankinderman), [\#275](https://github.com/typhoeus/typhoeus/pull/275))
|
6
18
|
|
7
19
|
## 0.6.2
|
8
20
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -4,7 +4,7 @@ Like a modern code version of the mythical beast with 100 serpent heads, Typhoeu
|
|
4
4
|
|
5
5
|
## Example
|
6
6
|
|
7
|
-
|
7
|
+
A single request:
|
8
8
|
|
9
9
|
```ruby
|
10
10
|
Typhoeus.get("www.example.com", followlocation: true)
|
@@ -29,9 +29,9 @@ gem "typhoeus"
|
|
29
29
|
|
30
30
|
## Project Tracking
|
31
31
|
|
32
|
-
* [Documentation](http://rubydoc.info/github/typhoeus/typhoeus/frames/Typhoeus) (
|
32
|
+
* [Documentation](http://rubydoc.info/github/typhoeus/typhoeus/frames/Typhoeus) (GitHub master)
|
33
33
|
* [Website](http://typhoeus.github.com/) (v0.4.2)
|
34
|
-
* [
|
34
|
+
* [Mailing list](http://groups.google.com/group/typhoeus)
|
35
35
|
|
36
36
|
## LICENSE
|
37
37
|
|
data/lib/typhoeus.rb
CHANGED
@@ -11,27 +11,27 @@ require 'typhoeus/request'
|
|
11
11
|
require 'typhoeus/response'
|
12
12
|
require 'typhoeus/version'
|
13
13
|
|
14
|
-
# If we are using any Rack
|
15
|
-
#
|
14
|
+
# If we are using any Rack-based application, then we need the Typhoeus rack
|
15
|
+
# middleware to ensure our app is running properly.
|
16
16
|
if defined?(Rack)
|
17
17
|
require "rack/typhoeus"
|
18
18
|
end
|
19
19
|
|
20
|
-
# If we are using Rails then we will include the Typhoeus railtie.
|
20
|
+
# If we are using Rails, then we will include the Typhoeus railtie.
|
21
21
|
# if defined?(Rails)
|
22
22
|
# require "typhoeus/railtie"
|
23
23
|
# end
|
24
24
|
|
25
|
-
# Typhoeus is a
|
25
|
+
# Typhoeus is a HTTP client library based on Ethon which
|
26
26
|
# wraps libcurl. Sitting on top of libcurl makes Typhoeus
|
27
27
|
# very reliable and fast.
|
28
28
|
#
|
29
29
|
# There are some gems using Typhoeus like
|
30
30
|
# {https://github.com/myronmarston/vcr VCR},
|
31
|
-
# {https://github.com/bblimke/webmock
|
31
|
+
# {https://github.com/bblimke/webmock WebMock} or
|
32
32
|
# {https://github.com/technoweenie/faraday Faraday}. VCR
|
33
|
-
# and
|
34
|
-
#
|
33
|
+
# and WebMock provide their own adapter whereas
|
34
|
+
# Faraday relies on {Faraday::Adapter::Typhoeus}
|
35
35
|
# since Typhoeus version 0.5.
|
36
36
|
#
|
37
37
|
# @example (see Typhoeus::Request)
|
@@ -47,7 +47,7 @@ module Typhoeus
|
|
47
47
|
extend Request::Actions
|
48
48
|
extend Request::Callbacks::Types
|
49
49
|
|
50
|
-
# The default
|
50
|
+
# The default Typhoeus user agent.
|
51
51
|
USER_AGENT = "Typhoeus - https://github.com/typhoeus/typhoeus"
|
52
52
|
|
53
53
|
# Set the Typhoeus configuration options by passing a block.
|
@@ -63,7 +63,7 @@ module Typhoeus
|
|
63
63
|
yield Config
|
64
64
|
end
|
65
65
|
|
66
|
-
# Stub out specific request.
|
66
|
+
# Stub out a specific request.
|
67
67
|
#
|
68
68
|
# @example (see Typhoeus::Expectation)
|
69
69
|
#
|
@@ -73,13 +73,15 @@ module Typhoeus
|
|
73
73
|
# @return [ Typhoeus::Expectation ] The expecatation.
|
74
74
|
#
|
75
75
|
# @see Typhoeus::Expectation
|
76
|
-
def stub(base_url, options = {})
|
76
|
+
def stub(base_url, options = {}, &block)
|
77
77
|
expectation = Expectation.all.find{ |e| e.base_url == base_url && e.options == options }
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
Expectation.all << new_expectation
|
78
|
+
if expectation.nil?
|
79
|
+
expectation = Expectation.new(base_url, options)
|
80
|
+
Expectation.all << expectation
|
82
81
|
end
|
82
|
+
|
83
|
+
expectation.and_return(&block) unless block.nil?
|
84
|
+
expectation
|
83
85
|
end
|
84
86
|
|
85
87
|
# Add before callbacks.
|
@@ -101,7 +103,7 @@ module Typhoeus
|
|
101
103
|
# Execute given block as if block connection is turned off.
|
102
104
|
# The old block connection state is restored afterwards.
|
103
105
|
#
|
104
|
-
# @example Make a real request, no matter if
|
106
|
+
# @example Make a real request, no matter if it's blocked.
|
105
107
|
# Typhoeus::Config.block_connection = true
|
106
108
|
# Typhoeus.get("www.example.com").code
|
107
109
|
# #=> raise Typhoeus::Errors::NoStub
|
@@ -113,7 +115,7 @@ module Typhoeus
|
|
113
115
|
#
|
114
116
|
# @param [ Block ] block The block to execute.
|
115
117
|
#
|
116
|
-
# @return [ Object ] Returns the return value of block.
|
118
|
+
# @return [ Object ] Returns the return value of the block.
|
117
119
|
#
|
118
120
|
# @see Typhoeus::Config#block_connection
|
119
121
|
def with_connection
|
@@ -18,6 +18,20 @@ module Faraday # :nodoc:
|
|
18
18
|
class Typhoeus < Faraday::Adapter
|
19
19
|
self.supports_parallel = true
|
20
20
|
|
21
|
+
(class << self; self; end).instance_eval do
|
22
|
+
remove_method :setup_parallel_manager if method_defined? :setup_parallel_manager
|
23
|
+
end
|
24
|
+
|
25
|
+
remove_method :call if method_defined? :call
|
26
|
+
remove_method :perform_request if method_defined? :perform_request
|
27
|
+
remove_method :request if method_defined? :request
|
28
|
+
remove_method :read_body if method_defined? :read_body
|
29
|
+
remove_method :configure_ssl if method_defined? :configure_ssl
|
30
|
+
remove_method :configure_proxy if method_defined? :configure_proxy
|
31
|
+
remove_method :configure_timeout if method_defined? :configure_timeout
|
32
|
+
remove_method :configure_socket if method_defined? :configure_socket
|
33
|
+
remove_method :parallel? if method_defined? :parallel?
|
34
|
+
|
21
35
|
# Setup Hydra with provided options.
|
22
36
|
#
|
23
37
|
# @example Setup Hydra.
|
data/lib/typhoeus/config.rb
CHANGED
@@ -7,16 +7,16 @@ module Typhoeus
|
|
7
7
|
# config.verbose = true
|
8
8
|
# end
|
9
9
|
#
|
10
|
-
# @example Set the configuration
|
10
|
+
# @example Set the configuration directly.
|
11
11
|
# Typhoeus::Config.verbose = true
|
12
12
|
module Config
|
13
13
|
extend self
|
14
14
|
|
15
|
-
# Defines
|
15
|
+
# Defines whether the connection is blocked.
|
16
16
|
# Defaults to false. When set to true, only
|
17
17
|
# stubbed requests are allowed. A
|
18
18
|
# {Typhoeus::Errors::NoStub} error is raised,
|
19
|
-
# when trying to do a real request.
|
19
|
+
# when trying to do a real request. It's possible
|
20
20
|
# to work around inside
|
21
21
|
# {Typhoeus#with_connection}.
|
22
22
|
#
|
@@ -28,7 +28,7 @@ module Typhoeus
|
|
28
28
|
# @see Typhoeus::Errors::NoStub
|
29
29
|
attr_accessor :block_connection
|
30
30
|
|
31
|
-
# Defines
|
31
|
+
# Defines whether GET requests are memoized when using the {Typhoeus::Hydra}.
|
32
32
|
#
|
33
33
|
# @return [ Boolean ]
|
34
34
|
#
|
@@ -36,7 +36,7 @@ module Typhoeus
|
|
36
36
|
# @see Typhoeus::Hydra::Memoizable
|
37
37
|
attr_accessor :memoize
|
38
38
|
|
39
|
-
# Defines
|
39
|
+
# Defines whether curls debug output is shown.
|
40
40
|
# Unfortunately it prints to stderr.
|
41
41
|
#
|
42
42
|
# @return [ Boolean ]
|
@@ -44,7 +44,7 @@ module Typhoeus
|
|
44
44
|
# @see http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTVERBOSE
|
45
45
|
attr_accessor :verbose
|
46
46
|
|
47
|
-
# Defines
|
47
|
+
# Defines whether requests are cached.
|
48
48
|
#
|
49
49
|
# @return [ Object ]
|
50
50
|
#
|
data/lib/typhoeus/errors.rb
CHANGED
data/lib/typhoeus/expectation.rb
CHANGED
@@ -2,10 +2,10 @@ module Typhoeus
|
|
2
2
|
|
3
3
|
# This class represents an expectation. It is part
|
4
4
|
# of the stubbing mechanism. An expectation contains
|
5
|
-
#
|
5
|
+
# a url and options, like a request. They are compared
|
6
6
|
# to the request url and options in order to evaluate
|
7
|
-
#
|
8
|
-
# responses
|
7
|
+
# whether they match. If that's the case, the attached
|
8
|
+
# responses are returned one by one.
|
9
9
|
#
|
10
10
|
# @example Stub a request and get specified response.
|
11
11
|
# expected = Typhoeus::Response.new
|
@@ -14,6 +14,30 @@ module Typhoeus
|
|
14
14
|
# actual = Typhoeus.get("www.example.com")
|
15
15
|
# expected == actual
|
16
16
|
# #=> true
|
17
|
+
#
|
18
|
+
# @example Stub a request and get a lazily-constructed response containing data from actual widgets that exist in the system when the stubbed request is made.
|
19
|
+
# Typhoeus.stub("www.example.com/widgets") do
|
20
|
+
# actual_widgets = Widget.all
|
21
|
+
# Typhoeus::Response.new(
|
22
|
+
# :body => actual_widgets.inject([]) do |ids, widget|
|
23
|
+
# ids << widget.id
|
24
|
+
# end.join(",")
|
25
|
+
# )
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# @example Stub a request and get a lazily-constructed response in the format requested.
|
29
|
+
# Typhoeus.stub("www.example.com") do |request|
|
30
|
+
# accept = (request.options[:headers]||{})['Accept'] || "application/json"
|
31
|
+
# format = accept.split(",").first
|
32
|
+
# body_obj = { 'things' => [ { 'id' => 'foo' } ] }
|
33
|
+
#
|
34
|
+
# Typhoeus::Response.new(
|
35
|
+
# :headers => {
|
36
|
+
# 'Content-Type' => format
|
37
|
+
# },
|
38
|
+
# :body => SERIALIZERS[format].serialize(body_obj)
|
39
|
+
# )
|
40
|
+
# end
|
17
41
|
class Expectation
|
18
42
|
|
19
43
|
# @api private
|
@@ -38,7 +62,7 @@ module Typhoeus
|
|
38
62
|
end
|
39
63
|
|
40
64
|
# Clears expectations. This is handy while
|
41
|
-
# testing and you want to make sure
|
65
|
+
# testing, and you want to make sure that
|
42
66
|
# you don't get canned responses.
|
43
67
|
#
|
44
68
|
# @example Clear expectations.
|
@@ -47,14 +71,24 @@ module Typhoeus
|
|
47
71
|
all.clear
|
48
72
|
end
|
49
73
|
|
50
|
-
# Returns
|
51
|
-
# request.
|
74
|
+
# Returns stubbed response matching the
|
75
|
+
# provided request.
|
52
76
|
#
|
53
|
-
# @example Find
|
54
|
-
# Typhoeus::Expectation.
|
77
|
+
# @example Find response
|
78
|
+
# Typhoeus::Expectation.response_for(request)
|
55
79
|
#
|
56
|
-
# @return [
|
80
|
+
# @return [ Typhoeus::Response ] The stubbed response from a
|
81
|
+
# matching expectation, or nil if no matching expectation
|
82
|
+
# is found.
|
57
83
|
#
|
84
|
+
# @api private
|
85
|
+
def response_for(request)
|
86
|
+
expectation = find_by(request)
|
87
|
+
return nil if expectation.nil?
|
88
|
+
|
89
|
+
expectation.response(request)
|
90
|
+
end
|
91
|
+
|
58
92
|
# @api private
|
59
93
|
def find_by(request)
|
60
94
|
all.find do |expectation|
|
@@ -79,7 +113,7 @@ module Typhoeus
|
|
79
113
|
end
|
80
114
|
|
81
115
|
# Set from value to mark an expectaion. Useful for
|
82
|
-
# other libraries,
|
116
|
+
# other libraries, e.g. WebMock.
|
83
117
|
#
|
84
118
|
# @example Mark expectation.
|
85
119
|
# expectation.from(:webmock)
|
@@ -101,11 +135,11 @@ module Typhoeus
|
|
101
135
|
# expectation.and_return(response)
|
102
136
|
#
|
103
137
|
# @return [ void ]
|
104
|
-
def and_return(response)
|
105
|
-
responses << response
|
138
|
+
def and_return(response=nil, &block)
|
139
|
+
responses << (response.nil? ? block : response)
|
106
140
|
end
|
107
141
|
|
108
|
-
# Checks
|
142
|
+
# Checks whether this expectation matches
|
109
143
|
# the provided request.
|
110
144
|
#
|
111
145
|
# @example Check if request matches.
|
@@ -133,7 +167,7 @@ module Typhoeus
|
|
133
167
|
end
|
134
168
|
|
135
169
|
# Return the response. When there are
|
136
|
-
# multiple responses, they
|
170
|
+
# multiple responses, they are returned one
|
137
171
|
# by one.
|
138
172
|
#
|
139
173
|
# @example Return response.
|
@@ -142,8 +176,11 @@ module Typhoeus
|
|
142
176
|
# @return [ Response ] The response.
|
143
177
|
#
|
144
178
|
# @api private
|
145
|
-
def response
|
179
|
+
def response(request)
|
146
180
|
response = responses.fetch(@response_counter, responses.last)
|
181
|
+
if response.respond_to?(:call)
|
182
|
+
response = response.call(request)
|
183
|
+
end
|
147
184
|
@response_counter += 1
|
148
185
|
response.mock = @from || true
|
149
186
|
response
|
@@ -151,15 +188,15 @@ module Typhoeus
|
|
151
188
|
|
152
189
|
private
|
153
190
|
|
154
|
-
# Check
|
191
|
+
# Check whether the options matches the request options.
|
155
192
|
# I checks options and original options.
|
156
193
|
def options_match?(request)
|
157
194
|
(options ? options.all?{ |k,v| request.original_options[k] == v || request.options[k] == v } : true)
|
158
195
|
end
|
159
196
|
|
160
|
-
# Check
|
197
|
+
# Check whether the base_url matches the request url.
|
161
198
|
# The base_url can be a string, regex or nil. String and
|
162
|
-
# regexp
|
199
|
+
# regexp are checked, nil is always true, else false.
|
163
200
|
#
|
164
201
|
# Nil serves as a placeholder in case you want to match
|
165
202
|
# all urls.
|
data/lib/typhoeus/hydra.rb
CHANGED
@@ -15,8 +15,8 @@ module Typhoeus
|
|
15
15
|
# @example Add the request.
|
16
16
|
# hydra.add(request)
|
17
17
|
def add(request)
|
18
|
-
if
|
19
|
-
request.finish(
|
18
|
+
if response = Expectation.response_for(request)
|
19
|
+
request.finish(response)
|
20
20
|
else
|
21
21
|
super
|
22
22
|
end
|
data/lib/typhoeus/pool.rb
CHANGED
@@ -12,8 +12,8 @@ module Typhoeus
|
|
12
12
|
|
13
13
|
@mutex = Mutex.new
|
14
14
|
|
15
|
-
# Releases easy into pool. The easy handle is
|
16
|
-
#
|
15
|
+
# Releases easy into the pool. The easy handle is
|
16
|
+
# reset before it gets back in.
|
17
17
|
#
|
18
18
|
# @example Release easy.
|
19
19
|
# hydra.release_easy(easy)
|
@@ -22,7 +22,7 @@ module Typhoeus
|
|
22
22
|
@mutex.synchronize { easies << easy }
|
23
23
|
end
|
24
24
|
|
25
|
-
# Return an easy from pool.
|
25
|
+
# Return an easy from the pool.
|
26
26
|
#
|
27
27
|
# @example Return easy.
|
28
28
|
# hydra.get_easy
|
data/lib/typhoeus/request.rb
CHANGED
@@ -42,7 +42,7 @@ module Typhoeus
|
|
42
42
|
# @return [ Hash ]
|
43
43
|
attr_accessor :options
|
44
44
|
|
45
|
-
# Returns the hydra the request ran
|
45
|
+
# Returns the hydra in which the request ran, if any.
|
46
46
|
#
|
47
47
|
# @return [ Typhoeus::Hydra ]
|
48
48
|
#
|
@@ -61,7 +61,7 @@ module Typhoeus
|
|
61
61
|
# @api private
|
62
62
|
attr_accessor :block_connection
|
63
63
|
|
64
|
-
#
|
64
|
+
# Creates a new request.
|
65
65
|
#
|
66
66
|
# @example Simplest request.
|
67
67
|
# response = Typhoeus::Request.new("www.example.com").run
|
@@ -126,14 +126,14 @@ module Typhoeus
|
|
126
126
|
EasyFactory.new(self).get.url
|
127
127
|
end
|
128
128
|
|
129
|
-
# Returns
|
129
|
+
# Returns whether other is equal to self.
|
130
130
|
#
|
131
131
|
# @example Are request equal?
|
132
132
|
# request.eql?(other_request)
|
133
133
|
#
|
134
134
|
# @param [ Object ] other The object to check.
|
135
135
|
#
|
136
|
-
# @return [ Boolean ] Returns true if
|
136
|
+
# @return [ Boolean ] Returns true if equal, else false.
|
137
137
|
#
|
138
138
|
# @api private
|
139
139
|
def eql?(other)
|
data/lib/typhoeus/response.rb
CHANGED
@@ -4,7 +4,7 @@ require 'typhoeus/response/status'
|
|
4
4
|
|
5
5
|
module Typhoeus
|
6
6
|
|
7
|
-
# This class
|
7
|
+
# This class represents the response.
|
8
8
|
class Response
|
9
9
|
include Response::Informations
|
10
10
|
include Response::Status
|
@@ -20,7 +20,7 @@ module Typhoeus
|
|
20
20
|
# @return [ Typhoeus::Request ]
|
21
21
|
attr_accessor :request
|
22
22
|
|
23
|
-
# The options
|
23
|
+
# The provided options, which contain all the
|
24
24
|
# informations about the request.
|
25
25
|
#
|
26
26
|
# @return [ Hash ]
|
@@ -45,7 +45,7 @@ module Typhoeus
|
|
45
45
|
@headers = Header.new(options[:headers]) if options[:headers]
|
46
46
|
end
|
47
47
|
|
48
|
-
# Returns
|
48
|
+
# Returns whether this request is mocked
|
49
49
|
# or not.
|
50
50
|
#
|
51
51
|
# @api private
|
@@ -54,7 +54,7 @@ module Typhoeus
|
|
54
54
|
end
|
55
55
|
|
56
56
|
# Returns the handled_response if it has
|
57
|
-
# been defined otherwise returns the response
|
57
|
+
# been defined; otherwise, returns the response
|
58
58
|
#
|
59
59
|
# @return [ Object ] The result of callbacks
|
60
60
|
# done on the response or the original response.
|
@@ -195,7 +195,7 @@ module Typhoeus
|
|
195
195
|
#
|
196
196
|
# @return [ Typhoeus::Header ] The response header.
|
197
197
|
def headers
|
198
|
-
return nil if response_headers.nil? && @headers
|
198
|
+
return nil if response_headers.nil? && !defined?(@headers)
|
199
199
|
@headers ||= Response::Header.new(response_headers.split("\r\n\r\n").last)
|
200
200
|
end
|
201
201
|
alias :headers_hash :headers
|
data/lib/typhoeus/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: typhoeus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2013-
|
14
|
+
date: 2013-04-09 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: ethon
|
@@ -20,7 +20,7 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - ~>
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 0.5.
|
23
|
+
version: 0.5.11
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
26
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -28,7 +28,7 @@ dependencies:
|
|
28
28
|
requirements:
|
29
29
|
- - ~>
|
30
30
|
- !ruby/object:Gem::Version
|
31
|
-
version: 0.5.
|
31
|
+
version: 0.5.11
|
32
32
|
description: Like a modern code version of the mythical beast with 100 serpent heads,
|
33
33
|
Typhoeus runs HTTP requests in parallel while cleanly encapsulating handling logic.
|
34
34
|
email:
|
@@ -94,7 +94,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
94
94
|
version: '0'
|
95
95
|
segments:
|
96
96
|
- 0
|
97
|
-
hash:
|
97
|
+
hash: 3937709754755965055
|
98
98
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
99
|
none: false
|
100
100
|
requirements:
|