goliath 0.9.1 → 0.9.2
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.
Potentially problematic release.
This version of goliath might be problematic. Click here for more details.
- data/.gitignore +1 -0
- data/HISTORY +50 -0
- data/README.md +2 -0
- data/examples/activerecord/srv.rb +1 -3
- data/examples/async_aroundware_demo.rb +81 -0
- data/examples/async_upload.rb +1 -2
- data/examples/auth_and_rate_limit.rb +143 -0
- data/examples/chunked_streaming.rb +37 -0
- data/examples/conf_test.rb +1 -3
- data/examples/config/auth_and_rate_limit.rb +30 -0
- data/examples/config/template.rb +8 -0
- data/examples/content_stream.rb +1 -3
- data/examples/echo.rb +8 -6
- data/examples/env_use_statements.rb +17 -0
- data/examples/gziped.rb +1 -3
- data/examples/public/stylesheets/style.css +296 -0
- data/examples/rack_routes.rb +65 -3
- data/examples/rasterize/rasterize.js +15 -0
- data/examples/rasterize/rasterize.rb +36 -0
- data/examples/rasterize/rasterize_and_shorten.rb +37 -0
- data/examples/stream.rb +2 -2
- data/examples/template.rb +48 -0
- data/examples/test_rig.rb +125 -0
- data/examples/valid.rb +4 -2
- data/examples/views/debug.haml +4 -0
- data/examples/views/joke.markdown +13 -0
- data/examples/views/layout.erb +12 -0
- data/examples/views/layout.haml +39 -0
- data/examples/views/root.haml +28 -0
- data/goliath.gemspec +10 -3
- data/lib/goliath.rb +0 -36
- data/lib/goliath/api.rb +137 -26
- data/lib/goliath/application.rb +71 -21
- data/lib/goliath/connection.rb +4 -2
- data/lib/goliath/constants.rb +1 -0
- data/lib/goliath/env.rb +40 -1
- data/lib/goliath/goliath.rb +30 -15
- data/lib/goliath/headers.rb +2 -2
- data/lib/goliath/plugins/latency.rb +8 -2
- data/lib/goliath/rack.rb +18 -0
- data/lib/goliath/rack/async_aroundware.rb +56 -0
- data/lib/goliath/rack/async_middleware.rb +93 -0
- data/lib/goliath/rack/builder.rb +42 -0
- data/lib/goliath/rack/default_response_format.rb +3 -15
- data/lib/goliath/rack/formatters.rb +11 -0
- data/lib/goliath/rack/formatters/html.rb +2 -18
- data/lib/goliath/rack/formatters/json.rb +2 -17
- data/lib/goliath/rack/formatters/plist.rb +32 -0
- data/lib/goliath/rack/formatters/xml.rb +23 -31
- data/lib/goliath/rack/formatters/yaml.rb +27 -0
- data/lib/goliath/rack/jsonp.rb +1 -13
- data/lib/goliath/rack/params.rb +55 -27
- data/lib/goliath/rack/render.rb +13 -22
- data/lib/goliath/rack/templates.rb +357 -0
- data/lib/goliath/rack/tracer.rb +11 -12
- data/lib/goliath/rack/validation.rb +12 -0
- data/lib/goliath/rack/validation/default_params.rb +0 -2
- data/lib/goliath/rack/validation/numeric_range.rb +11 -2
- data/lib/goliath/rack/validation/request_method.rb +3 -2
- data/lib/goliath/rack/validation/required_param.rb +13 -11
- data/lib/goliath/rack/validation/required_value.rb +11 -15
- data/lib/goliath/rack/validator.rb +51 -0
- data/lib/goliath/request.rb +34 -20
- data/lib/goliath/response.rb +3 -2
- data/lib/goliath/runner.rb +5 -11
- data/lib/goliath/server.rb +2 -1
- data/lib/goliath/synchrony/mongo_receiver.rb +64 -0
- data/lib/goliath/synchrony/response_receiver.rb +64 -0
- data/lib/goliath/test_helper.rb +39 -21
- data/lib/goliath/validation.rb +2 -0
- data/lib/goliath/{rack/validation_error.rb → validation/error.rb} +0 -16
- data/lib/goliath/validation/standard_http_errors.rb +31 -0
- data/lib/goliath/version.rb +1 -1
- data/spec/integration/http_log_spec.rb +16 -16
- data/spec/integration/rack_routes_spec.rb +144 -0
- data/spec/integration/reloader_spec.rb +4 -4
- data/spec/integration/template_spec.rb +54 -0
- data/spec/integration/trace_spec.rb +23 -0
- data/spec/integration/valid_spec.rb +21 -0
- data/spec/spec_helper.rb +3 -1
- data/spec/unit/api_spec.rb +30 -0
- data/spec/unit/rack/builder_spec.rb +40 -0
- data/spec/unit/rack/formatters/plist_spec.rb +51 -0
- data/spec/unit/rack/formatters/yaml_spec.rb +53 -0
- data/spec/unit/rack/params_spec.rb +22 -0
- data/spec/unit/rack/render_spec.rb +10 -5
- data/spec/unit/rack/validation/numeric_range_spec.rb +8 -1
- data/spec/unit/rack/validation/request_method_spec.rb +8 -8
- data/spec/unit/rack/validation/required_param_spec.rb +19 -15
- data/spec/unit/rack/validation/required_value_spec.rb +10 -13
- data/spec/unit/server_spec.rb +4 -4
- data/spec/unit/validation/standard_http_errors_spec.rb +21 -0
- metadata +177 -35
- data/spec/unit/rack/validation_error_spec.rb +0 -40
@@ -0,0 +1,357 @@
|
|
1
|
+
require 'tilt'
|
2
|
+
require 'goliath/validation/standard_http_errors'
|
3
|
+
|
4
|
+
module Goliath
|
5
|
+
module Rack
|
6
|
+
|
7
|
+
# Template rendering methods. Each method takes t as a Symbol (for template
|
8
|
+
# file lookup) or as a String (to render directly), as well as an optional
|
9
|
+
# hashes giving additional options and local variables. It returns a String
|
10
|
+
# with the rendered output.
|
11
|
+
#
|
12
|
+
# This is mostly similar to the code from Sinatra (indeed, it's stolen from
|
13
|
+
# there). It does not compile or cache templates, and the find_template
|
14
|
+
# method is simpler.
|
15
|
+
#
|
16
|
+
# @author Sinatra project -- https://github.com/sinatra/sinatra/contributors
|
17
|
+
module Templates
|
18
|
+
# lets us decorate the string response with a .content_type accessor
|
19
|
+
# @private
|
20
|
+
module ContentTyped
|
21
|
+
attr_accessor :content_type
|
22
|
+
end
|
23
|
+
|
24
|
+
# Render an erb template
|
25
|
+
#
|
26
|
+
# @param template [Symbol, String] Template Path (symbol) or contents (String)
|
27
|
+
# @param options [Hash] Rendering options -- see {#render}
|
28
|
+
# @param locals [Hash] Template-local variables -- see {#render}
|
29
|
+
# @return [String] The rendered template
|
30
|
+
# @see #render
|
31
|
+
def erb(template, options = {}, locals = {})
|
32
|
+
render :erb, template, options, locals
|
33
|
+
end
|
34
|
+
|
35
|
+
# Render an erubis template
|
36
|
+
#
|
37
|
+
# @param template [Symbol, String] Template Path (symbol) or contents (String)
|
38
|
+
# @param options [Hash] Rendering options -- see {#render}
|
39
|
+
# @param locals [Hash] Template-local variables -- see {#render}
|
40
|
+
# @return [String] The rendered template
|
41
|
+
# @see #render
|
42
|
+
def erubis(template, options = {}, locals = {})
|
43
|
+
render :erubis, template, options, locals
|
44
|
+
end
|
45
|
+
|
46
|
+
# Render a haml template
|
47
|
+
#
|
48
|
+
# @param template [Symbol, String] Template Path (symbol) or contents (String)
|
49
|
+
# @param options [Hash] Rendering options -- see {#render}
|
50
|
+
# @param locals [Hash] Template-local variables -- see {#render}
|
51
|
+
# @return [String] The rendered template
|
52
|
+
# @see #render
|
53
|
+
def haml(template, options = {}, locals = {})
|
54
|
+
render :haml, template, options, locals
|
55
|
+
end
|
56
|
+
|
57
|
+
# Render a sass template
|
58
|
+
#
|
59
|
+
# @param template [Symbol, String] Template Path (symbol) or contents (String)
|
60
|
+
# @param options [Hash] Rendering options -- see {#render}
|
61
|
+
# @param locals [Hash] Template-local variables -- see {#render}
|
62
|
+
# @return [String] The rendered template
|
63
|
+
# @see #render
|
64
|
+
def sass(template, options = {}, locals = {})
|
65
|
+
options.merge! :layout => false, :default_content_type => :css
|
66
|
+
render :sass, template, options, locals
|
67
|
+
end
|
68
|
+
|
69
|
+
# Render an scss template
|
70
|
+
#
|
71
|
+
# @param template [Symbol, String] Template Path (symbol) or contents (String)
|
72
|
+
# @param options [Hash] Rendering options -- see {#render}
|
73
|
+
# @param locals [Hash] Template-local variables -- see {#render}
|
74
|
+
# @return [String] The rendered template
|
75
|
+
# @see #render
|
76
|
+
def scss(template, options = {}, locals = {})
|
77
|
+
options.merge! :layout => false, :default_content_type => :css
|
78
|
+
render :scss, template, options, locals
|
79
|
+
end
|
80
|
+
|
81
|
+
# Render a less template
|
82
|
+
#
|
83
|
+
# @param template [Symbol, String] Template Path (symbol) or contents (String)
|
84
|
+
# @param options [Hash] Rendering options -- see {#render}
|
85
|
+
# @param locals [Hash] Template-local variables -- see {#render}
|
86
|
+
# @return [String] The rendered template
|
87
|
+
# @see #render
|
88
|
+
def less(template, options = {}, locals = {})
|
89
|
+
options.merge! :layout => false, :default_content_type => :css
|
90
|
+
render :less, template, options, locals
|
91
|
+
end
|
92
|
+
|
93
|
+
# Render a builder template
|
94
|
+
#
|
95
|
+
# @example
|
96
|
+
# # produces:
|
97
|
+
# # <?xml version='1.0' encoding='UTF-8'?>
|
98
|
+
# # <person>
|
99
|
+
# # <name aka='Frank Sinatra'>Francis Albert Sinatra</name>
|
100
|
+
# # <email>Frank Sinatra</email>
|
101
|
+
# # </person>
|
102
|
+
# builder do |xml|
|
103
|
+
# xml.instruct!
|
104
|
+
# xml.person do
|
105
|
+
# xml.name "Francis Albert Sinatra", :aka => "Frank Sinatra"
|
106
|
+
# xml.email 'frank@capitolrecords.com'
|
107
|
+
# end
|
108
|
+
# end
|
109
|
+
#
|
110
|
+
# @param template [Symbol, String] Template Path (symbol) or contents (String)
|
111
|
+
# @param options [Hash] Rendering options -- see {#render}
|
112
|
+
# @param locals [Hash] Template-local variables -- see {#render}
|
113
|
+
# @yield block If the builder method is given a block, the block is called directly
|
114
|
+
# with an XmlMarkup instance and used as a template.
|
115
|
+
# @return [String] The rendered template
|
116
|
+
# @see #render
|
117
|
+
def builder(template = nil, options = {}, locals = {}, &block)
|
118
|
+
options[:default_content_type] = :xml
|
119
|
+
render_ruby(:builder, template, options, locals, &block)
|
120
|
+
end
|
121
|
+
|
122
|
+
# Render a liquid template
|
123
|
+
#
|
124
|
+
# @param template [Symbol, String] Template Path (symbol) or contents (String)
|
125
|
+
# @param options [Hash] Rendering options -- see {#render}
|
126
|
+
# @param locals [Hash] Template-local variables -- see {#render}
|
127
|
+
# @return [String] The rendered template
|
128
|
+
# @see #render
|
129
|
+
def liquid(template, options = {}, locals = {})
|
130
|
+
render :liquid, template, options, locals
|
131
|
+
end
|
132
|
+
|
133
|
+
# Render a markdown template
|
134
|
+
#
|
135
|
+
# @param template [Symbol, String] Template Path (symbol) or contents (String)
|
136
|
+
# @param options [Hash] Rendering options -- see {#render}
|
137
|
+
# @param locals [Hash] Template-local variables -- see {#render}
|
138
|
+
# @return [String] The rendered template
|
139
|
+
# @see #render
|
140
|
+
def markdown(template, options = {}, locals = {})
|
141
|
+
render :markdown, template, options, locals
|
142
|
+
end
|
143
|
+
|
144
|
+
# Render a textile template
|
145
|
+
#
|
146
|
+
# @param template [Symbol, String] Template Path (symbol) or contents (String)
|
147
|
+
# @param options [Hash] Rendering options -- see {#render}
|
148
|
+
# @param locals [Hash] Template-local variables -- see {#render}
|
149
|
+
# @return [String] The rendered template
|
150
|
+
# @see #render
|
151
|
+
def textile(template, options = {}, locals = {})
|
152
|
+
render :textile, template, options, locals
|
153
|
+
end
|
154
|
+
|
155
|
+
# Render an rdoc template
|
156
|
+
#
|
157
|
+
# @param template [Symbol, String] Template Path (symbol) or contents (String)
|
158
|
+
# @param options [Hash] Rendering options -- see {#render}
|
159
|
+
# @param locals [Hash] Template-local variables -- see {#render}
|
160
|
+
# @return [String] The rendered template
|
161
|
+
# @see #render
|
162
|
+
def rdoc(template, options = {}, locals = {})
|
163
|
+
render :rdoc, template, options, locals
|
164
|
+
end
|
165
|
+
|
166
|
+
# Render a radius template
|
167
|
+
#
|
168
|
+
# @param template [Symbol, String] Template Path (symbol) or contents (String)
|
169
|
+
# @param options [Hash] Rendering options -- see {#render}
|
170
|
+
# @param locals [Hash] Template-local variables -- see {#render}
|
171
|
+
# @return [String] The rendered template
|
172
|
+
# @see #render
|
173
|
+
def radius(template, options = {}, locals = {})
|
174
|
+
render :radius, template, options, locals
|
175
|
+
end
|
176
|
+
|
177
|
+
# Render a markaby template
|
178
|
+
#
|
179
|
+
# @example
|
180
|
+
# markaby do
|
181
|
+
# html do
|
182
|
+
# head { title "Sinatra With Markaby" }
|
183
|
+
# body { h1 "Markaby Is Fun!" }
|
184
|
+
# end
|
185
|
+
# end
|
186
|
+
#
|
187
|
+
# @param template [Symbol, String] Template Path (symbol) or contents (String)
|
188
|
+
# @param options [Hash] Rendering options -- see {#render}
|
189
|
+
# @param locals [Hash] Template-local variables -- see {#render}
|
190
|
+
# @yield block A block template
|
191
|
+
# @return [String] The rendered template
|
192
|
+
# @see #render
|
193
|
+
def markaby(template = nil, options = {}, locals = {}, &block)
|
194
|
+
render_ruby(:mab, template, options, locals, &block)
|
195
|
+
end
|
196
|
+
|
197
|
+
# Render a coffee template
|
198
|
+
#
|
199
|
+
# @param template [Symbol, String] Template Path (symbol) or contents (String)
|
200
|
+
# @param options [Hash] Rendering options -- see {#render}
|
201
|
+
# @param locals [Hash] Template-local variables -- see {#render}
|
202
|
+
# @return [String] The rendered template
|
203
|
+
# @see #render
|
204
|
+
def coffee(template, options = {}, locals = {})
|
205
|
+
options.merge! :layout => false, :default_content_type => :js
|
206
|
+
render :coffee, template, options, locals
|
207
|
+
end
|
208
|
+
|
209
|
+
# Render a nokogiri template
|
210
|
+
#
|
211
|
+
# @example
|
212
|
+
# # produces
|
213
|
+
# # <ul>
|
214
|
+
# # <li>hello</li>
|
215
|
+
# # <li class="current">admin</li>
|
216
|
+
# # </ul>
|
217
|
+
# nokogiri do |doc|
|
218
|
+
# doc.ul do
|
219
|
+
# doc.li 'hello'
|
220
|
+
# doc.li 'admin', :class => 'current' if current_user.is_admin?
|
221
|
+
# end
|
222
|
+
# end
|
223
|
+
#
|
224
|
+
# @param template [Symbol, String] Template Path (symbol) or contents (String)
|
225
|
+
# @param options [Hash] Rendering options -- see {#render}
|
226
|
+
# @param locals [Hash] Template-local variables -- see {#render}
|
227
|
+
# @yield block A block template
|
228
|
+
# @return [String] The rendered template
|
229
|
+
# @see #render
|
230
|
+
def nokogiri(template = nil, options = {}, locals = {}, &block)
|
231
|
+
options[:default_content_type] = :xml
|
232
|
+
render_ruby(:nokogiri, template, options, locals, &block)
|
233
|
+
end
|
234
|
+
|
235
|
+
# Render a slim template
|
236
|
+
#
|
237
|
+
# @param template [Symbol, String] Template Path (symbol) or contents (String)
|
238
|
+
# @param options [Hash] Rendering options -- see {#render}
|
239
|
+
# @param locals [Hash] Template-local variables -- see {#render}
|
240
|
+
# @return [String] The rendered template
|
241
|
+
# @see #render
|
242
|
+
def slim(template, options = {}, locals = {})
|
243
|
+
render :slim, template, options, locals
|
244
|
+
end
|
245
|
+
|
246
|
+
# Finds template file with same name as extension
|
247
|
+
#
|
248
|
+
# @param views [String] The view directory
|
249
|
+
# @param name [String] The template name
|
250
|
+
# @param engine [String] The template type
|
251
|
+
# @return [String | nil] Template file or nil if it doesn't exist.
|
252
|
+
def find_template(views, name, engine)
|
253
|
+
filename = ::File.join(views, "#{name}.#{engine}")
|
254
|
+
File.exists?(filename) ? filename : nil
|
255
|
+
end
|
256
|
+
|
257
|
+
# Renders a template with the given engine. Don't call this directly --
|
258
|
+
# call one of the sugar methods.
|
259
|
+
#
|
260
|
+
# @param engine [Symbol] The engine (:haml, :erb, :textile, etc) to use
|
261
|
+
# @param template [Symbol, String] Either the name or path of the template as symbol
|
262
|
+
# (Use `:'subdir/myview'` for views in subdirectories), or a string that
|
263
|
+
# will be rendered. It looks for templates in
|
264
|
+
# +Goliath::Application.root_path/views+ by default. It is not as clever
|
265
|
+
# as Sinatra: you must name your template file template_name.engine_name
|
266
|
+
# -- so 'foo.markdown', not 'foo.md'.
|
267
|
+
#
|
268
|
+
# @param options [Hash] Options for layout
|
269
|
+
# @option options :content_type [String] The MIME content type to use.
|
270
|
+
# @option options [String] :layout If false, no layout is rendered, otherwise the specified layout is used.
|
271
|
+
# @option options [String] :layout_engine Engine to use for rendering the layout.
|
272
|
+
# @option options [Hash] :locals A hash with local variables that should be available in the template
|
273
|
+
# @option options [Object] :scope If set, template is evaluate with the binding of the
|
274
|
+
# given object rather than the application instance.
|
275
|
+
# @option options [String] :views Views directory to use.
|
276
|
+
#
|
277
|
+
# You may set template-global defaults in config[:template], for example
|
278
|
+
#
|
279
|
+
# config[:template] = {
|
280
|
+
# :layout_engine => :haml,
|
281
|
+
# }
|
282
|
+
#
|
283
|
+
# and engine-specific defaults in config[:template_engines], for example
|
284
|
+
#
|
285
|
+
# config[:template_engines] = {
|
286
|
+
# :haml => {
|
287
|
+
# :escape_html => true
|
288
|
+
# }
|
289
|
+
# }
|
290
|
+
#
|
291
|
+
# @param locals [Hash] You can give a hash of local variables available to
|
292
|
+
# the template either directly in +options[:local]+ or in a
|
293
|
+
# separate hash as the last parameter.
|
294
|
+
# @return [String] The rendered template
|
295
|
+
def render(engine, data, options = {}, locals = {}, &block)
|
296
|
+
# merge app-level options
|
297
|
+
if config.has_key?(:template_engines) && config[:template_engines].has_key?(engine)
|
298
|
+
options = config[:template_engines][engine].merge(options)
|
299
|
+
end
|
300
|
+
|
301
|
+
options = config[:template].merge(options) if config.has_key?(:template)
|
302
|
+
|
303
|
+
# extract generic options
|
304
|
+
locals = options.delete(:locals) || locals || {}
|
305
|
+
views = options.delete(:views) || Goliath::Application.root_path('views')
|
306
|
+
|
307
|
+
default_layout = options.delete(:default_layout) || :layout
|
308
|
+
|
309
|
+
layout = options.delete(:layout)
|
310
|
+
layout = default_layout if layout.nil? || layout == true
|
311
|
+
|
312
|
+
content_type = options.delete(:content_type) || options.delete(:default_content_type)
|
313
|
+
layout_engine = options.delete(:layout_engine) || engine
|
314
|
+
scope = options.delete(:scope) || self
|
315
|
+
|
316
|
+
layout_filename = find_template(views, layout, layout_engine)
|
317
|
+
|
318
|
+
layout_template = if layout == false || layout_filename == nil
|
319
|
+
NullLayout
|
320
|
+
else
|
321
|
+
Tilt.new(layout_filename, nil, options)
|
322
|
+
end
|
323
|
+
|
324
|
+
template_filename = find_template(views, data, engine)
|
325
|
+
unless template_filename
|
326
|
+
raise Goliath::Validation::InternalServerError, "Template #{data} not found in #{views} for #{engine}"
|
327
|
+
end
|
328
|
+
|
329
|
+
template = Tilt.new(template_filename, nil, options)
|
330
|
+
output = layout_template.render(scope, locals) do
|
331
|
+
template.render(scope, locals)
|
332
|
+
end
|
333
|
+
|
334
|
+
output.extend(ContentTyped).content_type = content_type if content_type
|
335
|
+
output
|
336
|
+
end
|
337
|
+
|
338
|
+
private
|
339
|
+
|
340
|
+
# Acts like a layout, does nothing.
|
341
|
+
# @private
|
342
|
+
class NullLayout
|
343
|
+
def self.render(*args, &block)
|
344
|
+
block.call
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
# logic shared between builder and nokogiri
|
349
|
+
def render_ruby(engine, template, options = {}, locals = {}, &block)
|
350
|
+
options, template = template, nil if template.is_a?(Hash)
|
351
|
+
template = Proc.new { block } if template.nil?
|
352
|
+
|
353
|
+
render engine, template, options, locals
|
354
|
+
end
|
355
|
+
end
|
356
|
+
end
|
357
|
+
end
|
data/lib/goliath/rack/tracer.rb
CHANGED
@@ -6,24 +6,23 @@ module Goliath
|
|
6
6
|
# use Goliath::Rack::Tracer
|
7
7
|
#
|
8
8
|
class Tracer
|
9
|
-
|
10
|
-
|
9
|
+
include Goliath::Rack::AsyncMiddleware
|
10
|
+
|
11
|
+
def initialize(app, header_name=nil)
|
12
|
+
super(app)
|
13
|
+
@header_name = header_name || 'X-PostRank'
|
11
14
|
end
|
12
15
|
|
13
16
|
def call(env)
|
14
|
-
|
15
|
-
|
16
|
-
env
|
17
|
-
|
18
|
-
env.logger.info env.trace_stats.collect{|s| s.join(':')}.join(', ')
|
19
|
-
end
|
20
|
-
|
21
|
-
status, headers, body = @app.call(env)
|
22
|
-
post_process(env, status, headers, body)
|
17
|
+
env.trace 'trace.start'
|
18
|
+
shb = super(env)
|
19
|
+
env.logger.info env.trace_stats.collect{|s| s.join(':')}.join(', ')
|
20
|
+
shb
|
23
21
|
end
|
24
22
|
|
25
23
|
def post_process(env, status, headers, body)
|
26
|
-
extra = {
|
24
|
+
extra = { @header_name => env.trace_stats.collect{|s| s.join(': ')}.join(', ')}
|
25
|
+
env.logger.info env.trace_stats.collect{|s| s.join(':')}.join(', ')
|
27
26
|
[status, headers.merge(extra), body]
|
28
27
|
end
|
29
28
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Goliath
|
2
|
+
module Rack
|
3
|
+
module Validation
|
4
|
+
autoload :BooleanValue, 'goliath/rack/validation/boolean_value'
|
5
|
+
autoload :DefaultParams, 'goliath/rack/validation/default_params'
|
6
|
+
autoload :NumericRange, 'goliath/rack/validation/numeric_range'
|
7
|
+
autoload :RequestMethod, 'goliath/rack/validation/request_method'
|
8
|
+
autoload :RequiredParam, 'goliath/rack/validation/required_param'
|
9
|
+
autoload :RequiredValue, 'goliath/rack/validation/required_value'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -7,6 +7,7 @@ module Goliath
|
|
7
7
|
#
|
8
8
|
# @example
|
9
9
|
# use Goliath::Rack::Validation::NumericRange, {:key => 'num', :min => 1, :max => 30, :default => 10}
|
10
|
+
# use Goliath::Rack::Validation::NumericRange, {:key => 'num', :min => 1.2, :max => 3.5, :default => 2.9, :as => Float}
|
10
11
|
# use Goliath::Rack::Validation::NumericRange, {:key => 'num', :min => 1}
|
11
12
|
# use Goliath::Rack::Validation::NumericRange, {:key => 'num', :max => 10}
|
12
13
|
#
|
@@ -18,6 +19,7 @@ module Goliath
|
|
18
19
|
# @option opts [String] :key The key to look for in the parameters
|
19
20
|
# @option opts [Integer] :min The minimum value
|
20
21
|
# @option opts [Integer] :max The maximum value
|
22
|
+
# @option opts [Class] :as How to convert: Float will use .to_f, Integer (the default) will use .to_i
|
21
23
|
# @option opts [Integer] :default The default to set if outside the range
|
22
24
|
# @return [Goliath::Rack::Validation::NumericRange] The validator
|
23
25
|
def initialize(app, opts = {})
|
@@ -29,6 +31,9 @@ module Goliath
|
|
29
31
|
@max = opts[:max]
|
30
32
|
raise Exception.new("NumericRange requires :min or :max") if @min.nil? && @max.nil?
|
31
33
|
|
34
|
+
@coerce_as = opts[:as]
|
35
|
+
raise Exception.new("NumericRange requires :as to be Float or Integer (default)") unless [nil, Integer, Float].include?(@coerce_as)
|
36
|
+
|
32
37
|
@default = opts[:default]
|
33
38
|
end
|
34
39
|
|
@@ -40,7 +45,7 @@ module Goliath
|
|
40
45
|
if env['params'][@key].instance_of?(Array) then
|
41
46
|
env['params'][@key] = env['params'][@key].first
|
42
47
|
end
|
43
|
-
env['params'][@key] = env['params'][@key]
|
48
|
+
env['params'][@key] = coerce(env['params'][@key])
|
44
49
|
|
45
50
|
if (!@min.nil? && env['params'][@key] < @min) || (!@max.nil? && env['params'][@key] > @max)
|
46
51
|
env['params'][@key] = value
|
@@ -50,10 +55,14 @@ module Goliath
|
|
50
55
|
@app.call(env)
|
51
56
|
end
|
52
57
|
|
58
|
+
def coerce(val)
|
59
|
+
(@coerce_as == Float) ? val.to_f : val.to_i
|
60
|
+
end
|
61
|
+
|
53
62
|
def value
|
54
63
|
@default || @min || @max
|
55
64
|
end
|
56
65
|
end
|
57
66
|
end
|
58
67
|
end
|
59
|
-
end
|
68
|
+
end
|