rester 0.4.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rester/client/adapters/adapter.rb +16 -57
- data/lib/rester/client/adapters/http_adapter/connection.rb +12 -34
- data/lib/rester/client/adapters/http_adapter.rb +5 -15
- data/lib/rester/client/adapters/local_adapter.rb +6 -17
- data/lib/rester/client/adapters/stub_adapter.rb +40 -19
- data/lib/rester/service/resource/params.rb +71 -18
- data/lib/rester/utils/stub_file.rb +1 -1
- data/lib/rester/utils.rb +37 -11
- data/lib/rester/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0d4b971390eaa9fe9c3aa6abdfb754f141bd8bb
|
4
|
+
data.tar.gz: 23c86151fc635c434a83249f85b0a66f66bf93ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3782bdebc01e6c081ab57224f025b9c8abc0f5002b83f3cf120b67626232f42855910714885e0d0f49572eb011b8e3e537f175fa0aa13e4d0db3e5d7c9e9839c
|
7
|
+
data.tar.gz: 6fe88686d1afa14ee878b4868ee3e67e201ca4ede8dfdaf0a9c4ab4369b81812cf51542aad5cd6cbec05042c0e624547af3457aabc4d5bd030d0111092406792
|
@@ -36,11 +36,22 @@ module Rester
|
|
36
36
|
raise NotImplementedError
|
37
37
|
end
|
38
38
|
|
39
|
-
|
40
|
-
|
39
|
+
##
|
40
|
+
# Sends an HTTP request to the service.
|
41
|
+
#
|
42
|
+
# `params` should be a hash if specified.
|
43
|
+
def request(verb, path, params = nil)
|
41
44
|
_validate_verb(verb)
|
42
|
-
|
43
|
-
|
45
|
+
request!(verb, path.to_s, Utils.encode_www_data(params))
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Sends an HTTP request to the service.
|
50
|
+
#
|
51
|
+
# `encoded_data` should be URL encoded set of parameters
|
52
|
+
# (e.g., "key1=value1&key2=value2")
|
53
|
+
def request!(verb, path, encoded_data)
|
54
|
+
fail NotImplementedError
|
44
55
|
end
|
45
56
|
|
46
57
|
[:get, :post, :put, :delete].each do |verb|
|
@@ -49,13 +60,6 @@ module Rester
|
|
49
60
|
define_method(verb) { |*args|
|
50
61
|
request(verb, *args)
|
51
62
|
}
|
52
|
-
|
53
|
-
##
|
54
|
-
# Define implementation methods: get!, post!, put!, delete!
|
55
|
-
# These methods should be overridden by the specific adapter.
|
56
|
-
define_method("#{verb}!") { |*args|
|
57
|
-
raise NotImplementedError
|
58
|
-
}
|
59
63
|
end
|
60
64
|
|
61
65
|
protected
|
@@ -73,54 +77,9 @@ module Rester
|
|
73
77
|
delete: true
|
74
78
|
}.freeze
|
75
79
|
|
76
|
-
##
|
77
|
-
# PARAM_KEY_TRANSFORMERS
|
78
|
-
#
|
79
|
-
# Defines how to transform a key value before being sent to the server.
|
80
|
-
# At the moment, this is a simple to_s conversion.
|
81
|
-
PARAM_KEY_TRANSFORMERS = Hash.new { |_, key|
|
82
|
-
proc { |value|
|
83
|
-
fail ArgumentError, "Invalid param key type: #{key.inspect}"
|
84
|
-
}
|
85
|
-
}.merge(
|
86
|
-
String => :to_s.to_proc,
|
87
|
-
Symbol => :to_s.to_proc
|
88
|
-
).freeze
|
89
|
-
|
90
|
-
##
|
91
|
-
# PARAM_VALUE_TRANSFORMERS
|
92
|
-
#
|
93
|
-
# Defines how values should be transformed before being sent to the
|
94
|
-
# server. Mostly, this is just a simple conversion to a string, but in
|
95
|
-
# the case of `nil` we want to convert it to 'null'.
|
96
|
-
PARAM_VALUE_TRANSFORMERS = Hash.new { |_, key|
|
97
|
-
proc { |value|
|
98
|
-
fail ArgumentError, "Invalid param value type: #{key.inspect}"
|
99
|
-
}
|
100
|
-
}.merge(
|
101
|
-
String => :to_s.to_proc,
|
102
|
-
Symbol => :to_s.to_proc,
|
103
|
-
Fixnum => :to_s.to_proc,
|
104
|
-
Integer => :to_s.to_proc,
|
105
|
-
Float => :to_s.to_proc,
|
106
|
-
DateTime => :to_s.to_proc,
|
107
|
-
TrueClass => :to_s.to_proc,
|
108
|
-
FalseClass => :to_s.to_proc,
|
109
|
-
NilClass => proc { 'null' }
|
110
|
-
).freeze
|
111
|
-
|
112
80
|
def _validate_verb(verb)
|
113
81
|
VALID_VERBS[verb] or
|
114
|
-
|
115
|
-
end
|
116
|
-
|
117
|
-
def _validate_params(params)
|
118
|
-
params.map { |key, value|
|
119
|
-
[
|
120
|
-
PARAM_KEY_TRANSFORMERS[key.class].call(key),
|
121
|
-
PARAM_VALUE_TRANSFORMERS[value.class].call(value)
|
122
|
-
]
|
123
|
-
}.to_h
|
82
|
+
fail ArgumentError, "Invalid verb: #{verb.inspect}"
|
124
83
|
end
|
125
84
|
end # Adapter
|
126
85
|
end # Client::Adapters
|
@@ -18,44 +18,18 @@ module Rester
|
|
18
18
|
@timeout = opts[:timeout]
|
19
19
|
end
|
20
20
|
|
21
|
-
def
|
21
|
+
def request(verb, path, params={})
|
22
22
|
_request(
|
23
|
-
|
23
|
+
verb,
|
24
24
|
_path(path, params[:query]),
|
25
|
-
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
def delete(path, params={})
|
30
|
-
_request(
|
31
|
-
:delete,
|
32
|
-
_path(path, params[:query]),
|
33
|
-
_prepare_headers(params[:headers])
|
34
|
-
)
|
35
|
-
end
|
36
|
-
|
37
|
-
def put(path, params={})
|
38
|
-
_request(
|
39
|
-
:put,
|
40
|
-
_path(path),
|
41
|
-
_prepare_data_headers(params[:headers]),
|
42
|
-
_encode_data(params[:data])
|
43
|
-
)
|
44
|
-
end
|
45
|
-
|
46
|
-
def post(path, params={})
|
47
|
-
_request(
|
48
|
-
:post,
|
49
|
-
_path(path),
|
50
|
-
_prepare_data_headers(params[:headers]),
|
51
|
-
_encode_data(params[:data])
|
25
|
+
_headers(verb, params[:headers]),
|
26
|
+
params[:data]
|
52
27
|
)
|
53
28
|
end
|
54
29
|
|
55
30
|
private
|
56
31
|
|
57
|
-
def _request(verb, path, headers
|
58
|
-
data = nil if [:get, :delete].include?(verb)
|
32
|
+
def _request(verb, path, headers, data)
|
59
33
|
_http.public_send(verb, *[path, data, headers].compact)
|
60
34
|
rescue Net::ReadTimeout, Net::OpenTimeout
|
61
35
|
fail Errors::TimeoutError
|
@@ -64,12 +38,16 @@ module Rester
|
|
64
38
|
def _path(path, query=nil)
|
65
39
|
u = url.dup
|
66
40
|
u.path = Utils.join_paths(u.path, path)
|
67
|
-
u.query =
|
41
|
+
u.query = query if query
|
68
42
|
u.request_uri
|
69
43
|
end
|
70
44
|
|
71
|
-
def
|
72
|
-
|
45
|
+
def _headers(verb, headers)
|
46
|
+
if [:post, :put].include?(verb)
|
47
|
+
_prepare_data_headers(headers)
|
48
|
+
else
|
49
|
+
_prepare_headers(headers)
|
50
|
+
end
|
73
51
|
end
|
74
52
|
|
75
53
|
def _prepare_data_headers(headers)
|
@@ -25,24 +25,14 @@ module Rester
|
|
25
25
|
!!connection
|
26
26
|
end
|
27
27
|
|
28
|
-
def
|
28
|
+
def request!(verb, path, encoded_data)
|
29
29
|
_require_connection
|
30
|
-
_prepare_response(connection.get(path, headers: headers, query: params))
|
31
|
-
end
|
32
30
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
31
|
+
data_key = [:get, :delete].include?(verb) ? :query : :data
|
32
|
+
response = connection.request(verb, path,
|
33
|
+
headers: headers, data_key => encoded_data)
|
37
34
|
|
38
|
-
|
39
|
-
_require_connection
|
40
|
-
_prepare_response(connection.put(path, headers: headers, data: params))
|
41
|
-
end
|
42
|
-
|
43
|
-
def post!(path, params={})
|
44
|
-
_require_connection
|
45
|
-
_prepare_response(connection.post(path, headers: headers, data: params))
|
35
|
+
_prepare_response(response)
|
46
36
|
end
|
47
37
|
|
48
38
|
private
|
@@ -12,7 +12,7 @@ module Rester
|
|
12
12
|
|
13
13
|
class << self
|
14
14
|
def can_connect_to?(service)
|
15
|
-
service.is_a?(Class) && service < Service
|
15
|
+
service.is_a?(Class) && !!(service < Service)
|
16
16
|
end
|
17
17
|
end # Class Methods
|
18
18
|
|
@@ -24,27 +24,16 @@ module Rester
|
|
24
24
|
!!service
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
def delete!(path, params={})
|
32
|
-
_request(:delete, path, headers: headers, query: params)
|
33
|
-
end
|
34
|
-
|
35
|
-
def put!(path, params={})
|
36
|
-
_request(:put, path, headers: headers, data: params)
|
37
|
-
end
|
38
|
-
|
39
|
-
def post!(path, params={})
|
40
|
-
_request(:post, path, headers: headers, data: params)
|
27
|
+
def request!(verb, path, encoded_data)
|
28
|
+
data_key = [:get, :delete].include?(verb) ? :query : :data
|
29
|
+
_request(verb, path, headers: headers, data_key => encoded_data)
|
41
30
|
end
|
42
31
|
|
43
32
|
private
|
44
33
|
|
45
34
|
def _request(verb, path, opts={})
|
46
|
-
body =
|
47
|
-
query =
|
35
|
+
body = opts[:data] || ''
|
36
|
+
query = opts[:query] || ''
|
48
37
|
|
49
38
|
response = Timeout::timeout(timeout) do
|
50
39
|
service.call(
|
@@ -30,20 +30,9 @@ module Rester
|
|
30
30
|
!!stub
|
31
31
|
end
|
32
32
|
|
33
|
-
def
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
def post!(path, params={})
|
38
|
-
_request('POST', path, params)
|
39
|
-
end
|
40
|
-
|
41
|
-
def put!(path, params={})
|
42
|
-
_request('PUT', path, params)
|
43
|
-
end
|
44
|
-
|
45
|
-
def delete!(path, params={})
|
46
|
-
_request('DELETE', path, params)
|
33
|
+
def request!(verb, path, encoded_data)
|
34
|
+
params = Rack::Utils.parse_nested_query(encoded_data)
|
35
|
+
_request(verb.to_s.upcase, path, params)
|
47
36
|
end
|
48
37
|
|
49
38
|
def with_context(context)
|
@@ -60,8 +49,13 @@ module Rester
|
|
60
49
|
end
|
61
50
|
|
62
51
|
def _process_request(path, verb, params)
|
63
|
-
|
64
|
-
|
52
|
+
unless stub[path]
|
53
|
+
fail Errors::StubError, "#{path} not found"
|
54
|
+
end
|
55
|
+
|
56
|
+
unless stub[path][verb]
|
57
|
+
fail Errors::StubError, "#{verb} #{path} not found"
|
58
|
+
end
|
65
59
|
|
66
60
|
context = @_context || _find_context_by_params(path, verb, params)
|
67
61
|
|
@@ -70,10 +64,13 @@ module Rester
|
|
70
64
|
"#{verb} #{path} with context '#{context}' not found"
|
71
65
|
end
|
72
66
|
|
73
|
-
# Verify
|
74
|
-
|
67
|
+
# Verify request params. Compile a list of mismatched params values and
|
68
|
+
# any incoming request param keys which aren't specified in the stub
|
69
|
+
unless (spec_params = spec['request']) == params
|
70
|
+
diff = _param_diff(params, spec_params)
|
75
71
|
fail Errors::StubError,
|
76
|
-
"#{verb} #{path} with context '#{context}' params don't match
|
72
|
+
"#{verb} #{path} with context '#{context}' params don't match "\
|
73
|
+
"stub: #{diff}"
|
77
74
|
end
|
78
75
|
|
79
76
|
# At this point, the 'request' is valid by matching a corresponding
|
@@ -81,6 +78,30 @@ module Rester
|
|
81
78
|
stub[path][verb][context]
|
82
79
|
end
|
83
80
|
|
81
|
+
##
|
82
|
+
# Generate the diff string in the case when the request params of the
|
83
|
+
# service don't match the params specified in the stub file.
|
84
|
+
def _param_diff(params, spec_params)
|
85
|
+
params = params.dup
|
86
|
+
# Compile a list of mismatched params values
|
87
|
+
diff = spec_params.map { |k,v|
|
88
|
+
param_value = params.delete(k)
|
89
|
+
unless v == param_value
|
90
|
+
"#{k.inspect} should equal #{v.inspect} but got "\
|
91
|
+
"#{param_value.inspect}"
|
92
|
+
end
|
93
|
+
}.compact.join(', ')
|
94
|
+
|
95
|
+
unless params.empty?
|
96
|
+
# Add any param keys which aren't specified in the spec
|
97
|
+
diff << ', and ' unless diff.empty?
|
98
|
+
unexpected_str = params.keys.map(&:to_s).map(&:inspect).join(', ')
|
99
|
+
diff << "received unexpected key(s): #{unexpected_str}"
|
100
|
+
end
|
101
|
+
|
102
|
+
diff
|
103
|
+
end
|
104
|
+
|
84
105
|
##
|
85
106
|
# Find the first request object with the same params as what's passed in.
|
86
107
|
# Useful for testing without having to set the context.
|
@@ -2,7 +2,7 @@ module Rester
|
|
2
2
|
class Service::Resource
|
3
3
|
class Params
|
4
4
|
DEFAULT_OPTS = { strict: true }.freeze
|
5
|
-
BASIC_TYPES = [String, Symbol, Float, Integer].freeze
|
5
|
+
BASIC_TYPES = [String, Symbol, Float, Integer, Array, Hash].freeze
|
6
6
|
|
7
7
|
DEFAULT_TYPE_MATCHERS = {
|
8
8
|
Integer => /\A\d+\z/,
|
@@ -59,14 +59,8 @@ module Rester
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def validate!(key, value)
|
62
|
-
_error!("expected string value for #{key}") unless value.is_a?(String)
|
63
|
-
|
64
62
|
klass, opts = @_validators[key]
|
65
|
-
|
66
|
-
|
67
|
-
_parse_with_class(klass, value).tap do |obj|
|
68
|
-
_validate_obj(key, obj)
|
69
|
-
end
|
63
|
+
_validate(key, value, klass, opts)
|
70
64
|
end
|
71
65
|
|
72
66
|
def use(params)
|
@@ -74,6 +68,10 @@ module Rester
|
|
74
68
|
nil
|
75
69
|
end
|
76
70
|
|
71
|
+
def required?(key)
|
72
|
+
@_required_fields.include?(key.to_sym)
|
73
|
+
end
|
74
|
+
|
77
75
|
##
|
78
76
|
# The basic data types all have helper methods named after them in Kernel.
|
79
77
|
# This allows you to do things like String(1234) to get '1234'. It's the
|
@@ -83,7 +81,13 @@ module Rester
|
|
83
81
|
# them so we can capture their calls. If this weren't the case, then we'd
|
84
82
|
# be catch them in `method_missing`.
|
85
83
|
BASIC_TYPES.each do |type|
|
86
|
-
define_method(type.to_s) { |name, opts={}|
|
84
|
+
define_method(type.to_s) { |name, opts={}, &block|
|
85
|
+
if type == Hash || (type == Array && opts[:type] == Hash)
|
86
|
+
elem_type = (options = @options.merge(opts)).delete(:type)
|
87
|
+
opts = elem_type ? { type: elem_type } : {}
|
88
|
+
opts.merge!(use: self.class.new(options, &block))
|
89
|
+
end
|
90
|
+
|
87
91
|
_add_validator(name, type, opts)
|
88
92
|
}
|
89
93
|
end
|
@@ -167,9 +171,49 @@ module Rester
|
|
167
171
|
raise error if error
|
168
172
|
end
|
169
173
|
|
170
|
-
|
171
|
-
|
174
|
+
##
|
175
|
+
# Validates and parses a given value. `klass` is the intended type for the
|
176
|
+
# value (e.g., String, Integer, Array, etc.). `opts` contains the
|
177
|
+
# validation options.
|
178
|
+
def _validate(key, value, klass, opts)
|
179
|
+
case value
|
180
|
+
when String
|
181
|
+
_validate_str(key, value, klass, opts)
|
182
|
+
when Array
|
183
|
+
_validate_array(key, value, klass, opts)
|
184
|
+
when Hash
|
185
|
+
_validate_hash(key, value, klass, opts)
|
186
|
+
when NilClass
|
187
|
+
_validate_required(key, false)
|
188
|
+
else
|
189
|
+
_error!("unexpected value type for #{key}: #{value.class}")
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def _validate_str(key, value, klass, opts)
|
194
|
+
fail unless value.is_a?(String) # assert
|
195
|
+
|
196
|
+
_validate_match(key, value, opts[:match]) if opts[:match]
|
197
|
+
_parse_with_class(klass, value).tap do |obj|
|
198
|
+
_validate_type(key, obj, klass) if obj
|
199
|
+
_validate_obj(key, obj, opts)
|
200
|
+
end
|
201
|
+
end
|
172
202
|
|
203
|
+
def _validate_array(key, value, klass, opts)
|
204
|
+
_error!("unexpected array for #{key}") unless klass == Array
|
205
|
+
type = (opts = opts.dup).delete(:type) || String
|
206
|
+
|
207
|
+
value.each_with_index
|
208
|
+
.map { |e, i| _validate("#{key}[#{i}]", e, type, opts) }
|
209
|
+
end
|
210
|
+
|
211
|
+
def _validate_hash(key, value, klass, opts)
|
212
|
+
_error!("unexpected hash for #{key}") unless klass == Hash
|
213
|
+
(validator = opts[:use]) && validator.validate(value)
|
214
|
+
end
|
215
|
+
|
216
|
+
def _parse_with_class(klass, value)
|
173
217
|
if klass == String
|
174
218
|
value
|
175
219
|
elsif klass == Integer
|
@@ -185,13 +229,8 @@ module Rester
|
|
185
229
|
end
|
186
230
|
end
|
187
231
|
|
188
|
-
def _validate_obj(key, obj)
|
189
|
-
if obj.nil?
|
190
|
-
_error!("#{key} cannot be null")
|
191
|
-
end
|
192
|
-
|
193
|
-
klass, opts = @_validators[key]
|
194
|
-
_validate_type(key, obj, klass) if obj
|
232
|
+
def _validate_obj(key, obj, opts)
|
233
|
+
fail if obj.nil? # Assert, at this point should be guaranteed
|
195
234
|
|
196
235
|
opts.each do |opt, value|
|
197
236
|
case opt
|
@@ -213,6 +252,20 @@ module Rester
|
|
213
252
|
end
|
214
253
|
end
|
215
254
|
|
255
|
+
def _validate_required(key, is_defined)
|
256
|
+
unless is_defined
|
257
|
+
_, key, index = /(\w+)(\[\d+\])?/.match(key).to_a
|
258
|
+
|
259
|
+
if required?(key)
|
260
|
+
if index
|
261
|
+
_error!("#{key} cannot contain null elements")
|
262
|
+
else
|
263
|
+
_error!("#{key} cannot be null")
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
216
269
|
def _valid_type?(obj, type)
|
217
270
|
case type
|
218
271
|
when :boolean
|
@@ -56,7 +56,7 @@ module Rester
|
|
56
56
|
# Converts all the values in the request hash to strings, which mimics
|
57
57
|
# how the data will be received on the service side.
|
58
58
|
def _update_request(path, verb, context, spec)
|
59
|
-
spec['request'] = Utils.
|
59
|
+
spec['request'] = Utils.stringify(spec['request'] || {})
|
60
60
|
end
|
61
61
|
|
62
62
|
##
|
data/lib/rester/utils.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'date'
|
2
|
+
require 'uri'
|
2
3
|
|
3
4
|
module Rester
|
4
5
|
module Utils
|
@@ -20,6 +21,38 @@ module Rester
|
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
24
|
+
##
|
25
|
+
# Copied from Rack::Utils.build_nested_query (version 1.6.0)
|
26
|
+
#
|
27
|
+
# We want to be able to support Rack >= 1.5.2, but this method is broken
|
28
|
+
# in that version.
|
29
|
+
def encode_www_data(value, prefix = nil)
|
30
|
+
# Rack::Utils.build_nested_query(value)
|
31
|
+
case value
|
32
|
+
when Array
|
33
|
+
value.map { |v|
|
34
|
+
encode_www_data(v, "#{prefix}[]")
|
35
|
+
}.join("&")
|
36
|
+
when Hash
|
37
|
+
value.map { |k, v|
|
38
|
+
encode_www_data(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k))
|
39
|
+
}.reject(&:empty?).join('&')
|
40
|
+
when nil
|
41
|
+
prefix
|
42
|
+
else
|
43
|
+
raise ArgumentError, "value must be a Hash" if prefix.nil?
|
44
|
+
"#{prefix}=#{escape(value)}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def decode_www_data(data)
|
49
|
+
Rack::Utils.parse_nested_query(data)
|
50
|
+
end
|
51
|
+
|
52
|
+
def escape(value)
|
53
|
+
URI.encode_www_form_component(value)
|
54
|
+
end
|
55
|
+
|
23
56
|
def join_paths(*paths)
|
24
57
|
paths.map(&:to_s).reject { |p| p.nil? || p.empty? }
|
25
58
|
.join('/').gsub(/\/+/, '/')
|
@@ -50,17 +83,10 @@ module Rester
|
|
50
83
|
hash.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
|
51
84
|
end
|
52
85
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
memo[k] = stringify_vals(v)
|
58
|
-
when NilClass
|
59
|
-
memo[k] = 'null'
|
60
|
-
else
|
61
|
-
memo[k] = v.to_s
|
62
|
-
end
|
63
|
-
}
|
86
|
+
##
|
87
|
+
# Converts all keys and values to strings.
|
88
|
+
def stringify(hash={})
|
89
|
+
decode_www_data(encode_www_data(hash))
|
64
90
|
end
|
65
91
|
|
66
92
|
def classify(str)
|
data/lib/rester/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rester
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Honer
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-12-
|
12
|
+
date: 2015-12-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|