padrino-core 0.9.24 → 0.9.25
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/lib/padrino-core/application.rb +11 -22
- data/lib/padrino-core/application/rendering.rb +13 -4
- data/lib/padrino-core/application/routing.rb +159 -124
- data/lib/padrino-core/cli/base.rb +1 -0
- data/lib/padrino-core/cli/console.rb +1 -1
- data/lib/padrino-core/cli/rake.rb +5 -0
- data/lib/padrino-core/loader.rb +3 -6
- data/lib/padrino-core/logger.rb +13 -5
- data/lib/padrino-core/mounter.rb +35 -36
- data/lib/padrino-core/reloader.rb +4 -4
- data/lib/padrino-core/support_lite.rb +1 -1
- data/lib/padrino-core/version.rb +1 -1
- data/padrino-core.gemspec +3 -2
- data/test/fixtures/apps/simple.rb +1 -1
- data/test/test_logger.rb +18 -1
- data/test/test_mounter.rb +9 -4
- data/test/test_reloader_complex.rb +20 -18
- data/test/test_reloader_simple.rb +2 -1
- data/test/test_router.rb +2 -2
- data/test/test_routing.rb +70 -25
- metadata +35 -19
|
@@ -63,7 +63,7 @@ module Padrino
|
|
|
63
63
|
# MyApp.reset_routes!
|
|
64
64
|
#
|
|
65
65
|
def reset_routes!
|
|
66
|
-
|
|
66
|
+
reset_router!
|
|
67
67
|
default_routes!
|
|
68
68
|
end
|
|
69
69
|
|
|
@@ -84,7 +84,6 @@ module Padrino
|
|
|
84
84
|
#
|
|
85
85
|
def setup_application!
|
|
86
86
|
return if @_configured
|
|
87
|
-
self.calculate_paths
|
|
88
87
|
self.register_initializers
|
|
89
88
|
self.require_load_paths
|
|
90
89
|
self.disable :logging # We need do that as default because Sinatra use commonlogger.
|
|
@@ -134,7 +133,9 @@ module Padrino
|
|
|
134
133
|
set :padrino_logging, true
|
|
135
134
|
set :method_override, true
|
|
136
135
|
set :sessions, false
|
|
137
|
-
set :public, Proc.new { Padrino.root('public',
|
|
136
|
+
set :public, Proc.new { Padrino.root('public', uri_root) }
|
|
137
|
+
set :views, Proc.new { File.join(root, "views") }
|
|
138
|
+
set :images_path, Proc.new { File.join(public, "images") }
|
|
138
139
|
# Padrino specific
|
|
139
140
|
set :uri_root, "/"
|
|
140
141
|
set :reload, Proc.new { development? }
|
|
@@ -184,23 +185,13 @@ module Padrino
|
|
|
184
185
|
end
|
|
185
186
|
end
|
|
186
187
|
|
|
187
|
-
##
|
|
188
|
-
# Calculates any required paths after app_file and root have been properly configured
|
|
189
|
-
# Executes as part of the setup_application! method
|
|
190
|
-
#
|
|
191
|
-
def calculate_paths
|
|
192
|
-
raise ApplicationSetupError.new("Please define 'app_file' option for #{self.name} app!") unless self.app_file
|
|
193
|
-
set :views, find_view_path if find_view_path
|
|
194
|
-
set :images_path, File.join(self.public, "/images") unless self.respond_to?(:images_path)
|
|
195
|
-
end
|
|
196
|
-
|
|
197
188
|
##
|
|
198
189
|
# Requires the Padrino middleware
|
|
199
190
|
#
|
|
200
191
|
def register_initializers
|
|
201
|
-
use Padrino::Logger::Rack
|
|
202
|
-
use Padrino::Reloader::Rack
|
|
203
|
-
use Rack::Flash
|
|
192
|
+
use Padrino::Logger::Rack, uri_root if Padrino.logger && (Padrino.logger.level == 0 && padrino_logging?)
|
|
193
|
+
use Padrino::Reloader::Rack if reload?
|
|
194
|
+
use Rack::Flash if flash?
|
|
204
195
|
end
|
|
205
196
|
|
|
206
197
|
##
|
|
@@ -218,12 +209,10 @@ module Padrino
|
|
|
218
209
|
load_paths.each { |path| Padrino.require_dependencies(File.join(self.root, path)) }
|
|
219
210
|
end
|
|
220
211
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
@view_paths = ["views"].collect { |path| File.join(self.root, path) }
|
|
226
|
-
@view_paths.find { |path| Dir[File.join(path, '/**/*')].any? }
|
|
212
|
+
private
|
|
213
|
+
def setup_sessions(builder)
|
|
214
|
+
return unless sessions
|
|
215
|
+
builder.use Rack::Session::Cookie, :secret => session_secret, :path => uri_root
|
|
227
216
|
end
|
|
228
217
|
end # self
|
|
229
218
|
|
|
@@ -88,6 +88,8 @@ module Padrino
|
|
|
88
88
|
end
|
|
89
89
|
|
|
90
90
|
module InstanceMethods
|
|
91
|
+
attr_reader :current_engine
|
|
92
|
+
|
|
91
93
|
def content_type(type=nil, params={}) #:nodoc:
|
|
92
94
|
type.nil? ? @_content_type : super(type, params)
|
|
93
95
|
end
|
|
@@ -114,8 +116,8 @@ module Padrino
|
|
|
114
116
|
# If an engine is a string then this is a likely a path to be resolved
|
|
115
117
|
data, engine = *resolve_template(engine, options) if data.nil?
|
|
116
118
|
|
|
117
|
-
#
|
|
118
|
-
|
|
119
|
+
# Setup root
|
|
120
|
+
root = settings.respond_to?(:root) ? settings.root : ""
|
|
119
121
|
|
|
120
122
|
# Resolve layouts similar to in Rails
|
|
121
123
|
if (options[:layout].nil? || options[:layout] == true) && !settings.templates.has_key?(:layout)
|
|
@@ -123,14 +125,21 @@ module Padrino
|
|
|
123
125
|
options[:layout] = layout_path || false # We need to force layout false so sinatra don't try to render it
|
|
124
126
|
options[:layout] = false unless layout_engine == engine # TODO allow different layout engine
|
|
125
127
|
options[:layout_engine] = layout_engine || engine if options[:layout]
|
|
126
|
-
logger.debug "Resolving layout #{options[:layout]}" if defined?(logger) && options[:layout].present?
|
|
128
|
+
logger.debug "Resolving layout #{root}/views#{options[:layout]}" if defined?(logger) && options[:layout].present?
|
|
127
129
|
elsif options[:layout].present?
|
|
128
130
|
options[:layout] = settings.fetch_layout_path(options[:layout])
|
|
129
|
-
logger.debug "Resolving layout #{options[:layout]}" if defined?(logger)
|
|
131
|
+
logger.debug "Resolving layout #{root}/views#{options[:layout]}" if defined?(logger)
|
|
130
132
|
end
|
|
131
133
|
|
|
134
|
+
# Cleanup the template
|
|
135
|
+
@current_engine, engine_was = engine, @current_engine
|
|
136
|
+
@_out_buf, _buf_was = "", @_out_buf
|
|
137
|
+
|
|
132
138
|
# Pass arguments to Sinatra render method
|
|
133
139
|
super(engine, data, options.dup, locals, &block)
|
|
140
|
+
ensure
|
|
141
|
+
@current_engine = engine_was
|
|
142
|
+
@_out_buf = _buf_was
|
|
134
143
|
end
|
|
135
144
|
|
|
136
145
|
##
|
|
@@ -1,6 +1,60 @@
|
|
|
1
1
|
require 'http_router' unless defined?(HttpRouter)
|
|
2
2
|
require 'padrino-core/support_lite' unless defined?(SupportLite)
|
|
3
3
|
|
|
4
|
+
class Sinatra::Request
|
|
5
|
+
attr_accessor :route_obj
|
|
6
|
+
|
|
7
|
+
def controller
|
|
8
|
+
route_obj && route_obj.controller
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class HttpRouter #:nodoc:
|
|
13
|
+
attr_accessor :runner
|
|
14
|
+
class Route #:nodoc:
|
|
15
|
+
attr_reader :before_filters, :after_filters
|
|
16
|
+
attr_accessor :custom_conditions, :use_layout, :controller, :cache
|
|
17
|
+
|
|
18
|
+
def add_before_filter(filter)
|
|
19
|
+
@before_filters ||= []
|
|
20
|
+
@before_filters << filter
|
|
21
|
+
arbitrary { |req, params|
|
|
22
|
+
if req.testing_405?
|
|
23
|
+
true
|
|
24
|
+
else
|
|
25
|
+
old_params = router.runner.params
|
|
26
|
+
result = catch(:pass) {
|
|
27
|
+
router.runner.params ||= {}
|
|
28
|
+
router.runner.params.merge!(params)
|
|
29
|
+
router.runner.instance_eval(&filter)
|
|
30
|
+
true
|
|
31
|
+
} == true
|
|
32
|
+
router.runner.params = old_params
|
|
33
|
+
result
|
|
34
|
+
end
|
|
35
|
+
}
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def add_after_filter(filter)
|
|
39
|
+
@after_filters ||= []
|
|
40
|
+
@after_filters << filter
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def before_filters=(filters)
|
|
44
|
+
filters.each { |filter| add_before_filter(filter) } if filters
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def after_filters=(filters)
|
|
48
|
+
filters.each { |filter| add_after_filter(filter) } if filters
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def custom_conditions=(custom_conditions)
|
|
52
|
+
custom_conditions.each { |blk| arbitrary { |req, params| router.runner.instance_eval(&blk) != false } } if custom_conditions
|
|
53
|
+
@custom_conditions = custom_conditions
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
4
58
|
module Padrino
|
|
5
59
|
##
|
|
6
60
|
# Padrino provides advanced routing definition support to make routes and url generation much easier.
|
|
@@ -12,67 +66,6 @@ module Padrino
|
|
|
12
66
|
module Routing
|
|
13
67
|
CONTENT_TYPE_ALIASES = { :htm => :html }
|
|
14
68
|
|
|
15
|
-
class ::HttpRouter #:nodoc:
|
|
16
|
-
attr_accessor :runner
|
|
17
|
-
class Route #:nodoc:
|
|
18
|
-
attr_reader :before_filters, :after_filters
|
|
19
|
-
attr_accessor :custom_conditions, :use_layout, :controller, :cache
|
|
20
|
-
|
|
21
|
-
def add_before_filter(filter)
|
|
22
|
-
@before_filters ||= []
|
|
23
|
-
@before_filters << filter
|
|
24
|
-
arbitrary { |req, params, dest|
|
|
25
|
-
old_params = router.runner.params
|
|
26
|
-
result = catch(:pass) {
|
|
27
|
-
router.runner.params ||= {}
|
|
28
|
-
router.runner.params.merge!(params)
|
|
29
|
-
router.runner.instance_eval(&filter)
|
|
30
|
-
true
|
|
31
|
-
} == true
|
|
32
|
-
router.runner.params = old_params
|
|
33
|
-
result
|
|
34
|
-
}
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def add_after_filter(filter)
|
|
38
|
-
@after_filters ||= []
|
|
39
|
-
@after_filters << filter
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def before_filters=(filters)
|
|
43
|
-
filters.each { |filter| add_before_filter(filter) } if filters
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def after_filters=(filters)
|
|
47
|
-
filters.each { |filter| add_after_filter(filter) } if filters
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def custom_conditions=(custom_conditions)
|
|
51
|
-
custom_conditions.each { |blk| arbitrary { |req, params, dest| router.runner.instance_eval(&blk) != false } } if custom_conditions
|
|
52
|
-
@custom_conditions = custom_conditions
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
module ::Sinatra #:nodoc:
|
|
58
|
-
class Request #:nodoc:
|
|
59
|
-
attr_accessor :match
|
|
60
|
-
|
|
61
|
-
def controller
|
|
62
|
-
route && route.controller
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def route
|
|
66
|
-
if match.nil?
|
|
67
|
-
path = Rack::Utils.unescape(path_info)
|
|
68
|
-
path.empty? ? "/" : path
|
|
69
|
-
else
|
|
70
|
-
match.path.route
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
end # Request
|
|
74
|
-
end # Sinatra
|
|
75
|
-
|
|
76
69
|
class UnrecognizedException < RuntimeError #:nodoc:
|
|
77
70
|
end
|
|
78
71
|
|
|
@@ -240,6 +233,10 @@ module Padrino
|
|
|
240
233
|
end
|
|
241
234
|
alias :urls :router
|
|
242
235
|
|
|
236
|
+
def reset_router!
|
|
237
|
+
@router = HttpRouter.new
|
|
238
|
+
end
|
|
239
|
+
|
|
243
240
|
##
|
|
244
241
|
# Instance method for url generation like:
|
|
245
242
|
#
|
|
@@ -254,9 +251,8 @@ module Padrino
|
|
|
254
251
|
names, params_array = args.partition{|a| a.is_a?(Symbol)}
|
|
255
252
|
name = names.join("_").to_sym # route name is concatenated with underscores
|
|
256
253
|
if params.is_a?(Hash)
|
|
257
|
-
params.
|
|
258
|
-
params
|
|
259
|
-
params.each { |k,v| params[k] = v.to_param if v.respond_to?(:to_param) }
|
|
254
|
+
params[:format] = params[:format].to_s unless params[:format].nil?
|
|
255
|
+
params = value_to_param(params)
|
|
260
256
|
end
|
|
261
257
|
url = if params_array.empty?
|
|
262
258
|
router.url(name, params)
|
|
@@ -287,6 +283,21 @@ module Padrino
|
|
|
287
283
|
def head(path, *args, &bk); route 'HEAD', path, *args, &bk end
|
|
288
284
|
|
|
289
285
|
private
|
|
286
|
+
# Parse params from the url method
|
|
287
|
+
def value_to_param(value)
|
|
288
|
+
case value
|
|
289
|
+
when Array
|
|
290
|
+
value.map { |v| value_to_param(v) }.compact
|
|
291
|
+
when Hash
|
|
292
|
+
value.inject({}) do |memo, (k,v)|
|
|
293
|
+
v = value_to_param(v)
|
|
294
|
+
memo[k] = v unless v.nil?
|
|
295
|
+
memo
|
|
296
|
+
end
|
|
297
|
+
when nil then nil
|
|
298
|
+
else value.respond_to?(:to_param) ? value.to_param : value
|
|
299
|
+
end
|
|
300
|
+
end
|
|
290
301
|
|
|
291
302
|
# Add prefix slash if its not present and remove trailing slashes.
|
|
292
303
|
def conform_uri(uri_string)
|
|
@@ -317,19 +328,18 @@ module Padrino
|
|
|
317
328
|
#
|
|
318
329
|
def route(verb, path, *args, &block)
|
|
319
330
|
options = case args.size
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
raise
|
|
331
|
+
when 2
|
|
332
|
+
args.last.merge(:map => args.first)
|
|
333
|
+
when 1
|
|
334
|
+
map = args.shift if args.first.is_a?(String)
|
|
335
|
+
if args.first.is_a?(Hash)
|
|
336
|
+
map ? args.first.merge(:map => map) : args.first
|
|
337
|
+
else
|
|
338
|
+
{:map => map || args.first}
|
|
339
|
+
end
|
|
340
|
+
when 0
|
|
341
|
+
{}
|
|
342
|
+
else raise
|
|
333
343
|
end
|
|
334
344
|
|
|
335
345
|
# Do padrino parsing. We dup options so we can build HEAD request correctly
|
|
@@ -343,7 +353,11 @@ module Padrino
|
|
|
343
353
|
unbound_method = instance_method("#{verb} #{path}")
|
|
344
354
|
block =
|
|
345
355
|
if block.arity != 0
|
|
346
|
-
|
|
356
|
+
block_arity = block.arity
|
|
357
|
+
proc {
|
|
358
|
+
@block_params = @block_params.slice(0, block_arity) if block_arity > 0
|
|
359
|
+
unbound_method.bind(self).call(*@block_params)
|
|
360
|
+
}
|
|
347
361
|
else
|
|
348
362
|
proc { unbound_method.bind(self).call }
|
|
349
363
|
end
|
|
@@ -356,8 +370,11 @@ module Padrino
|
|
|
356
370
|
route.cache = options.key?(:cache) ? options.delete(:cache) : @_cache
|
|
357
371
|
route.send(verb.downcase.to_sym)
|
|
358
372
|
route.host(options.delete(:host)) if options.key?(:host)
|
|
359
|
-
route.
|
|
360
|
-
|
|
373
|
+
route.user_agent(options.delete(:agent)) if options.key?(:agent)
|
|
374
|
+
if options.key?(:default_values)
|
|
375
|
+
defaults = options.delete(:default_values)
|
|
376
|
+
route.default(defaults) if defaults
|
|
377
|
+
end
|
|
361
378
|
options.delete_if do |option, args|
|
|
362
379
|
if route.send(:significant_variable_names).include?(option)
|
|
363
380
|
route.matching(option => Array(args).first)
|
|
@@ -366,7 +383,13 @@ module Padrino
|
|
|
366
383
|
end
|
|
367
384
|
|
|
368
385
|
# Add Sinatra conditions
|
|
369
|
-
options.each { |option, args|
|
|
386
|
+
options.each { |option, args|
|
|
387
|
+
if route.respond_to?(option)
|
|
388
|
+
route.send(option, *args)
|
|
389
|
+
else
|
|
390
|
+
send(option, *args)
|
|
391
|
+
end
|
|
392
|
+
}
|
|
370
393
|
conditions, @conditions = @conditions, []
|
|
371
394
|
route.custom_conditions = conditions
|
|
372
395
|
|
|
@@ -383,6 +406,43 @@ module Padrino
|
|
|
383
406
|
route.after_filters = @filters[:after] || []
|
|
384
407
|
end
|
|
385
408
|
|
|
409
|
+
route.arbitrary_with_continue do |req, params|
|
|
410
|
+
if req.testing_405?
|
|
411
|
+
req.continue[true]
|
|
412
|
+
else
|
|
413
|
+
base = self
|
|
414
|
+
processed = false
|
|
415
|
+
router.runner.instance_eval do
|
|
416
|
+
request.route_obj = route
|
|
417
|
+
@_response_buffer = nil
|
|
418
|
+
if path.is_a?(Regexp)
|
|
419
|
+
params_list = req.extra_env['router.regex_match'].to_a
|
|
420
|
+
params_list.shift
|
|
421
|
+
@block_params = params_list
|
|
422
|
+
@params.update({:captures => params_list}.merge(@params || {}))
|
|
423
|
+
else
|
|
424
|
+
@block_params = req.params
|
|
425
|
+
@params.update(params.merge(@params || {}))
|
|
426
|
+
end
|
|
427
|
+
pass_block = catch(:pass) do
|
|
428
|
+
# If present set current controller layout
|
|
429
|
+
parent_layout = base.instance_variable_get(:@layout)
|
|
430
|
+
base.instance_variable_set(:@layout, route.use_layout) if route.use_layout
|
|
431
|
+
# Provide access to the current controller to the request
|
|
432
|
+
# Now we can eval route, but because we have "throw halt" we need to be
|
|
433
|
+
# (en)sure to reset old layout and run controller after filters.
|
|
434
|
+
begin
|
|
435
|
+
@_response_buffer = catch(:halt) { route_eval(&block) }
|
|
436
|
+
processed = true
|
|
437
|
+
ensure
|
|
438
|
+
base.instance_variable_set(:@layout, parent_layout) if route.use_layout
|
|
439
|
+
(@_pending_after_filters ||= []).concat(route.after_filters) if route.after_filters
|
|
440
|
+
end
|
|
441
|
+
end
|
|
442
|
+
end
|
|
443
|
+
req.continue[processed]
|
|
444
|
+
end
|
|
445
|
+
end
|
|
386
446
|
route.to(block)
|
|
387
447
|
route
|
|
388
448
|
end
|
|
@@ -420,10 +480,12 @@ module Padrino
|
|
|
420
480
|
|
|
421
481
|
if @_use_format or format_params = options[:provides]
|
|
422
482
|
process_path_for_provides(path, format_params)
|
|
483
|
+
options[:matching] ||= {}
|
|
484
|
+
options[:matching][:format] = /[^\.]+/
|
|
423
485
|
end
|
|
424
486
|
|
|
425
487
|
# Build our controller
|
|
426
|
-
controller = Array(@_controller).
|
|
488
|
+
controller = Array(@_controller).map { |c| c.to_s }
|
|
427
489
|
|
|
428
490
|
absolute_map = map && map[0] == ?/
|
|
429
491
|
|
|
@@ -451,6 +513,7 @@ module Padrino
|
|
|
451
513
|
path = "#{@_map}/#{path}".squeeze('/') unless absolute_map or @_map.blank?
|
|
452
514
|
|
|
453
515
|
# Small reformats
|
|
516
|
+
path.gsub!(%r{/\?$}, '(/)') # Remove index path
|
|
454
517
|
path.gsub!(%r{/?index/?}, '/') # Remove index path
|
|
455
518
|
path.gsub!(%r{//$}, '/') # Remove index path
|
|
456
519
|
path[0,0] = "/" unless path =~ %r{^\(?/} # Paths must start with a /
|
|
@@ -469,7 +532,7 @@ module Padrino
|
|
|
469
532
|
# Used for calculating path in route method
|
|
470
533
|
#
|
|
471
534
|
def process_path_for_with_params(path, with_params)
|
|
472
|
-
File.join(path, Array(with_params).
|
|
535
|
+
File.join(path, Array(with_params).map(&:inspect).join("/"))
|
|
473
536
|
end
|
|
474
537
|
|
|
475
538
|
##
|
|
@@ -477,7 +540,7 @@ module Padrino
|
|
|
477
540
|
# Used for calculating path in route method
|
|
478
541
|
#
|
|
479
542
|
def process_path_for_parent_params(path, parent_params)
|
|
480
|
-
parent_prefix = parent_params.flatten.compact.uniq.
|
|
543
|
+
parent_prefix = parent_params.flatten.compact.uniq.map do |param|
|
|
481
544
|
map = (param.respond_to?(:map) && param.map ? param.map : param.to_s)
|
|
482
545
|
part = "#{map}/:#{param}_id/"
|
|
483
546
|
part = "(#{part})" if param.respond_to?(:optional) && param.optional?
|
|
@@ -531,7 +594,8 @@ module Padrino
|
|
|
531
594
|
|
|
532
595
|
# per rfc2616-sec14:
|
|
533
596
|
# Assume */* if no ACCEPT header is given.
|
|
534
|
-
|
|
597
|
+
accepts.delete "*/*"
|
|
598
|
+
if accepts.empty?
|
|
535
599
|
matching_types = mime_types.slice(0,1)
|
|
536
600
|
else
|
|
537
601
|
matching_types = (accepts & mime_types)
|
|
@@ -552,15 +616,9 @@ module Padrino
|
|
|
552
616
|
# per rfc2616-sec14:
|
|
553
617
|
# answer with 406 if accept is given but types to not match any
|
|
554
618
|
# provided type
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
if settings.respond_to?(:treat_format_as_accept) && settings.treat_format_as_accept
|
|
560
|
-
if url_format && !matched_format
|
|
561
|
-
halt 406
|
|
562
|
-
end
|
|
563
|
-
end
|
|
619
|
+
halt 406 if
|
|
620
|
+
(!url_format && !accepts.empty? && !matched_format) ||
|
|
621
|
+
(settings.respond_to?(:treat_format_as_accept) && settings.treat_format_as_accept && url_format && !matched_format)
|
|
564
622
|
|
|
565
623
|
if matched_format
|
|
566
624
|
@_content_type = url_format || accept_format || :html
|
|
@@ -639,39 +697,14 @@ module Padrino
|
|
|
639
697
|
#
|
|
640
698
|
def route!(base=self.class, pass_block=nil)
|
|
641
699
|
base.router.runner = self
|
|
642
|
-
if base.router and match = base.router.recognize(@request)
|
|
643
|
-
if match.
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
if request.match.path.route.regex?
|
|
647
|
-
params_list = @request.env['rack.request.query_hash']['router.regex_match'].to_a
|
|
648
|
-
params_list.shift
|
|
649
|
-
@block_params = params_list
|
|
650
|
-
@params.update({:captures => params_list}.merge(@params || {}))
|
|
651
|
-
else
|
|
652
|
-
@block_params = matched_path.param_values
|
|
653
|
-
@params.update(matched_path.params.merge(@params || {}))
|
|
654
|
-
end
|
|
655
|
-
pass_block = catch(:pass) do
|
|
656
|
-
# If present set current controller layout
|
|
657
|
-
parent_layout = base.instance_variable_get(:@layout)
|
|
658
|
-
base.instance_variable_set(:@layout, matched_path.path.route.use_layout) if matched_path.path.route.use_layout
|
|
659
|
-
# Provide access to the current controller to the request
|
|
660
|
-
# Now we can eval route, but because we have "throw halt" we need to be
|
|
661
|
-
# (en)sure to reset old layout and run controller after filters.
|
|
662
|
-
begin
|
|
663
|
-
@_response_buffer = catch(:halt) { route_eval(&matched_path.path.route.dest) }
|
|
664
|
-
throw :halt, @_response_buffer
|
|
665
|
-
ensure
|
|
666
|
-
base.instance_variable_set(:@layout, parent_layout) if matched_path.path.route.use_layout
|
|
667
|
-
matched_path.path.route.after_filters.each { |aft| throw :pass if instance_eval(&aft) == false } if matched_path.path.route.after_filters
|
|
668
|
-
end
|
|
669
|
-
end
|
|
670
|
-
end
|
|
671
|
-
elsif match
|
|
700
|
+
if base.router and match = base.router.recognize(@request.env)
|
|
701
|
+
if match.respond_to?(:path)
|
|
702
|
+
throw :halt, @_response_buffer
|
|
703
|
+
elsif match.respond_to?(:each)
|
|
672
704
|
route_eval do
|
|
673
705
|
match[1].each {|k,v| response[k] = v}
|
|
674
706
|
status match[0]
|
|
707
|
+
route_missing if match[0] == 404
|
|
675
708
|
end
|
|
676
709
|
end
|
|
677
710
|
end
|
|
@@ -685,6 +718,8 @@ module Padrino
|
|
|
685
718
|
route_eval(&pass_block) if pass_block
|
|
686
719
|
|
|
687
720
|
route_missing
|
|
721
|
+
ensure
|
|
722
|
+
@_pending_after_filters.each { |aft| instance_eval(&aft) } if @_pending_after_filters
|
|
688
723
|
end
|
|
689
724
|
end # InstanceMethods
|
|
690
725
|
end # Routing
|
|
@@ -10,7 +10,7 @@ def applications
|
|
|
10
10
|
puts " * %-10s mapped to %s" % [app.name, app.uri_root]
|
|
11
11
|
end
|
|
12
12
|
puts
|
|
13
|
-
Padrino.mounted_apps.
|
|
13
|
+
Padrino.mounted_apps.map { |app| "#{app.name} => #{app.uri_root}" }
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
# Load apps
|
data/lib/padrino-core/loader.rb
CHANGED
|
@@ -43,7 +43,7 @@ module Padrino
|
|
|
43
43
|
set_load_paths(*load_paths) # We set the padrino load paths
|
|
44
44
|
Padrino.logger # Initialize our logger
|
|
45
45
|
before_load.each { |bl| bl.call } # Run before hooks
|
|
46
|
-
dependency_paths.each { |path|
|
|
46
|
+
dependency_paths.each { |path| require_dependencies(path) }
|
|
47
47
|
Reloader::Stat.run! # We need to fill our Stat::CACHE
|
|
48
48
|
after_load.each { |al| al.call } # Run after hooks
|
|
49
49
|
Thread.current[:padrino_loaded] = true
|
|
@@ -109,7 +109,6 @@ module Padrino
|
|
|
109
109
|
files.each do |file|
|
|
110
110
|
begin
|
|
111
111
|
Reloader::Stat.safe_load(file)
|
|
112
|
-
files.delete(file)
|
|
113
112
|
rescue LoadError => e
|
|
114
113
|
errors << e
|
|
115
114
|
failed << file
|
|
@@ -122,11 +121,10 @@ module Padrino
|
|
|
122
121
|
end
|
|
123
122
|
|
|
124
123
|
# Stop processing if nothing loads or if everything has loaded
|
|
125
|
-
raise errors.last if
|
|
126
|
-
break if
|
|
124
|
+
raise errors.last if failed.size == size_at_start
|
|
125
|
+
break if failed.empty?
|
|
127
126
|
end
|
|
128
127
|
end
|
|
129
|
-
alias :require_dependency :require_dependencies
|
|
130
128
|
|
|
131
129
|
##
|
|
132
130
|
# Returns default list of path globs to load as dependencies
|
|
@@ -160,7 +158,6 @@ module Padrino
|
|
|
160
158
|
FileSet.glob(path) { |file| load(file) }
|
|
161
159
|
end
|
|
162
160
|
end
|
|
163
|
-
alias :load_dependency :load_dependencies
|
|
164
161
|
|
|
165
162
|
##
|
|
166
163
|
# Concat to $LOAD_PATH the given paths
|
data/lib/padrino-core/logger.rb
CHANGED
|
@@ -30,6 +30,7 @@ module Padrino
|
|
|
30
30
|
attr_reader :buffer
|
|
31
31
|
attr_reader :log
|
|
32
32
|
attr_reader :init_args
|
|
33
|
+
attr_accessor :log_static
|
|
33
34
|
|
|
34
35
|
##
|
|
35
36
|
# Ruby (standard) logger levels:
|
|
@@ -63,6 +64,7 @@ module Padrino
|
|
|
63
64
|
# added. Defaults to true.
|
|
64
65
|
# :format_datetime:: Format of datetime. Defaults to: "%d/%b/%Y %H:%M:%S"
|
|
65
66
|
# :format_message:: Format of message. Defaults to: ""%s - - [%s] \"%s\"""
|
|
67
|
+
# :log_static:: Whether or not to show log messages for static files. Defaults to: false
|
|
66
68
|
#
|
|
67
69
|
# ==== Examples
|
|
68
70
|
#
|
|
@@ -146,6 +148,7 @@ module Padrino
|
|
|
146
148
|
# added. Defaults to true.
|
|
147
149
|
# :format_datetime:: Format of datetime. Defaults to: "%d/%b/%Y %H:%M:%S"
|
|
148
150
|
# :format_message:: Format of message. Defaults to: ""%s - - [%s] \"%s\"""
|
|
151
|
+
# :log_static:: Whether or not to show log messages for static files. Defaults to: false
|
|
149
152
|
#
|
|
150
153
|
def initialize(options={})
|
|
151
154
|
@buffer = []
|
|
@@ -156,6 +159,7 @@ module Padrino
|
|
|
156
159
|
@mutex = @@mutex[@log] ||= Mutex.new
|
|
157
160
|
@format_datetime = options[:format_datetime] || "%d/%b/%Y %H:%M:%S"
|
|
158
161
|
@format_message = options[:format_message] || "%s - [%s] \"%s\""
|
|
162
|
+
@log_static = options.has_key?(:log_static) ? options[:log_static] : false
|
|
159
163
|
end
|
|
160
164
|
|
|
161
165
|
##
|
|
@@ -271,10 +275,11 @@ module Padrino
|
|
|
271
275
|
# "lilith.local - - GET / HTTP/1.1 500 -"
|
|
272
276
|
# %{%s - %s %s %s%s %s - %d %s %0.4f}
|
|
273
277
|
#
|
|
274
|
-
FORMAT = %{%s
|
|
278
|
+
FORMAT = %{%s (%0.4fms) %s - %s %s%s%s %s - %d %s}
|
|
275
279
|
|
|
276
|
-
def initialize(app)
|
|
280
|
+
def initialize(app, uri_root)
|
|
277
281
|
@app = app
|
|
282
|
+
@uri_root = uri_root.sub(/\/$/,"")
|
|
278
283
|
end
|
|
279
284
|
|
|
280
285
|
def call(env)
|
|
@@ -289,16 +294,19 @@ module Padrino
|
|
|
289
294
|
now = Time.now
|
|
290
295
|
length = extract_content_length(header)
|
|
291
296
|
|
|
297
|
+
return if env['sinatra.static_file'] and !logger.log_static
|
|
298
|
+
|
|
292
299
|
logger.debug FORMAT % [
|
|
300
|
+
env["REQUEST_METHOD"],
|
|
301
|
+
now - began_at,
|
|
293
302
|
env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"] || "-",
|
|
294
303
|
env["REMOTE_USER"] || "-",
|
|
295
|
-
|
|
304
|
+
@uri_root || "",
|
|
296
305
|
env["PATH_INFO"],
|
|
297
306
|
env["QUERY_STRING"].empty? ? "" : "?" + env["QUERY_STRING"],
|
|
298
307
|
env["HTTP_VERSION"],
|
|
299
308
|
status.to_s[0..3],
|
|
300
|
-
length
|
|
301
|
-
now - began_at ]
|
|
309
|
+
length]
|
|
302
310
|
end
|
|
303
311
|
|
|
304
312
|
def extract_content_length(headers)
|
data/lib/padrino-core/mounter.rb
CHANGED
|
@@ -15,7 +15,7 @@ module Padrino
|
|
|
15
15
|
attr_accessor :name, :uri_root, :app_file, :app_class, :app_root, :app_obj, :app_host
|
|
16
16
|
|
|
17
17
|
def initialize(name, options={})
|
|
18
|
-
@name = name.to_s
|
|
18
|
+
@name = name.to_s
|
|
19
19
|
@app_class = options[:app_class] || @name.camelize
|
|
20
20
|
@app_file = options[:app_file] || locate_app_file
|
|
21
21
|
@app_obj = options[:app_obj] || app_constant || locate_app_object
|
|
@@ -115,45 +115,44 @@ module Padrino
|
|
|
115
115
|
end
|
|
116
116
|
|
|
117
117
|
protected
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
118
|
+
##
|
|
119
|
+
# Locates and requires the file to load the app constant
|
|
120
|
+
#
|
|
121
|
+
def locate_app_object
|
|
122
|
+
@_app_object ||= begin
|
|
123
|
+
ensure_app_file!
|
|
124
|
+
Padrino.require_dependencies(app_file)
|
|
125
|
+
app_constant
|
|
126
|
+
end
|
|
127
127
|
end
|
|
128
|
-
end
|
|
129
128
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
129
|
+
##
|
|
130
|
+
# Returns the determined location of the mounted application main file
|
|
131
|
+
#
|
|
132
|
+
def locate_app_file
|
|
133
|
+
candidates = []
|
|
134
|
+
candidates << app_constant.app_file if app_constant.respond_to?(:app_file) && File.exist?(app_constant.app_file.to_s)
|
|
135
|
+
candidates << Padrino.first_caller if File.identical?(Padrino.first_caller.to_s, Padrino.called_from.to_s)
|
|
136
|
+
candidates << Padrino.mounted_root(name, "app.rb")
|
|
137
|
+
candidates << Padrino.root("app", "app.rb")
|
|
138
|
+
candidates.find { |candidate| File.exist?(candidate) }
|
|
139
|
+
end
|
|
141
140
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
141
|
+
###
|
|
142
|
+
# Raises an exception unless app_file is located properly
|
|
143
|
+
#
|
|
144
|
+
def ensure_app_file!
|
|
145
|
+
message = "Unable to locate source file for app '#{app_class}', try with :app_file => '/path/app.rb'"
|
|
146
|
+
raise MounterException, message unless @app_file
|
|
147
|
+
end
|
|
149
148
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
149
|
+
###
|
|
150
|
+
# Raises an exception unless app_obj is defined properly
|
|
151
|
+
#
|
|
152
|
+
def ensure_app_object!
|
|
153
|
+
message = "Unable to locate app for '#{app_class}', try with :app_class => 'MyAppClass'"
|
|
154
|
+
raise MounterException, message unless @app_obj
|
|
155
|
+
end
|
|
157
156
|
end
|
|
158
157
|
|
|
159
158
|
class << self
|
|
@@ -34,10 +34,10 @@ module Padrino
|
|
|
34
34
|
|
|
35
35
|
##
|
|
36
36
|
# Specified folders can be excluded from the code reload detection process.
|
|
37
|
-
# Default excluded directories at Padrino.root are: test, spec, features, tmp, config,
|
|
37
|
+
# Default excluded directories at Padrino.root are: test, spec, features, tmp, config, db and public
|
|
38
38
|
#
|
|
39
39
|
def self.exclude
|
|
40
|
-
@_exclude ||= %w(test spec tmp features config
|
|
40
|
+
@_exclude ||= %w(test spec tmp features config public db).map { |path| Padrino.root(path) }
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
##
|
|
@@ -83,7 +83,7 @@ module Padrino
|
|
|
83
83
|
# We skip to next file if it is not new and not modified
|
|
84
84
|
next unless new_file || mtime > previous_mtime
|
|
85
85
|
# If the file is related to their app (i.e. a controller/mailer/helper)
|
|
86
|
-
|
|
86
|
+
Padrino.mounted_apps.find_all { |a| file =~ /^#{File.dirname(a.app_file)}/ }.each do |app|
|
|
87
87
|
# We need to reload their own app
|
|
88
88
|
app.app_obj.reload!
|
|
89
89
|
# App reloading will also perform safe_load of itself so we can go next
|
|
@@ -254,4 +254,4 @@ module Padrino
|
|
|
254
254
|
end # self
|
|
255
255
|
end # Stat
|
|
256
256
|
end # Reloader
|
|
257
|
-
end # Padrino
|
|
257
|
+
end # Padrino
|
|
@@ -52,7 +52,7 @@ if defined?(ActiveSupport::CoreExtensions::Hash) && !Hash.method_defined?(:slice
|
|
|
52
52
|
|
|
53
53
|
def ordered_collect(&block)
|
|
54
54
|
keys = self.stringify_keys.keys.sort
|
|
55
|
-
keys.
|
|
55
|
+
keys.map { |key| block.call(key, self[key.to_sym]) }
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
58
|
end
|
data/lib/padrino-core/version.rb
CHANGED
data/padrino-core.gemspec
CHANGED
|
@@ -17,8 +17,9 @@ Gem::Specification.new do |s|
|
|
|
17
17
|
s.files = %w(.document .gitignore LICENSE README.rdoc Rakefile padrino-core.gemspec) + Dir.glob("{bin,lib,test}/**/*")
|
|
18
18
|
s.rdoc_options = ["--charset=UTF-8"]
|
|
19
19
|
s.require_path = "lib"
|
|
20
|
-
s.add_dependency("
|
|
21
|
-
s.add_dependency("
|
|
20
|
+
s.add_dependency("tilt", "~> 1.3.0")
|
|
21
|
+
s.add_dependency("sinatra", "~> 1.2.3")
|
|
22
|
+
s.add_dependency("http_router", "~> 0.7.4")
|
|
22
23
|
s.add_dependency("thor", ">=0.14.3")
|
|
23
24
|
s.add_dependency("activesupport", ">= 3.0.0")
|
|
24
25
|
s.add_dependency("tzinfo")
|
data/test/test_logger.rb
CHANGED
|
@@ -48,8 +48,25 @@ class TestPadrinoLogger < Test::Unit::TestCase
|
|
|
48
48
|
mock_app { get("/"){ "Foo" } }
|
|
49
49
|
get "/"
|
|
50
50
|
assert_equal "Foo", body
|
|
51
|
-
assert_match /GET
|
|
51
|
+
assert_match /GET/, Padrino.logger.log.string
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
+
context "static asset logging" do
|
|
55
|
+
should 'not log static assets by default' do
|
|
56
|
+
mock_app { get("/images/something.png"){ env["sinatra.static_file"] = '/public/images/something.png'; "Foo" } }
|
|
57
|
+
get "/images/something.png"
|
|
58
|
+
assert_equal "Foo", body
|
|
59
|
+
assert_match "", Padrino.logger.log.string
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
should 'allow turning on static assets logging' do
|
|
63
|
+
Padrino.logger.instance_eval{ @log_static = true }
|
|
64
|
+
mock_app { get("/images/something.png"){ env["sinatra.static_file"] = '/public/images/something.png'; "Foo" } }
|
|
65
|
+
get "/images/something.png"
|
|
66
|
+
assert_equal "Foo", body
|
|
67
|
+
assert_match /GET/, Padrino.logger.log.string
|
|
68
|
+
Padrino.logger.instance_eval{ @log_static = false }
|
|
69
|
+
end
|
|
70
|
+
end
|
|
54
71
|
end
|
|
55
72
|
end
|
data/test/test_mounter.rb
CHANGED
|
@@ -3,9 +3,14 @@ require File.expand_path(File.dirname(__FILE__) + '/helper')
|
|
|
3
3
|
class TestMounter < Test::Unit::TestCase
|
|
4
4
|
|
|
5
5
|
def setup
|
|
6
|
+
$VERBOSE, @_verbose_was = nil, $VERBOSE
|
|
6
7
|
Padrino.mounted_apps.clear
|
|
7
8
|
end
|
|
8
9
|
|
|
10
|
+
def teardown
|
|
11
|
+
$VERBOSE = @_verbose_was
|
|
12
|
+
end
|
|
13
|
+
|
|
9
14
|
context 'for mounter functionality' do
|
|
10
15
|
|
|
11
16
|
should 'check methods' do
|
|
@@ -36,16 +41,16 @@ class TestMounter < Test::Unit::TestCase
|
|
|
36
41
|
class ::AnApp < Padrino::Application; end
|
|
37
42
|
Padrino.mount("an_app").to("/")
|
|
38
43
|
assert_equal AnApp, Padrino.mounted_apps.first.app_obj
|
|
39
|
-
assert_equal ["an_app"], Padrino.mounted_apps.
|
|
44
|
+
assert_equal ["an_app"], Padrino.mounted_apps.map(&:name)
|
|
40
45
|
end
|
|
41
|
-
|
|
46
|
+
|
|
42
47
|
should 'correctly mount an app in a namespace' do
|
|
43
48
|
module ::SomeNamespace
|
|
44
49
|
class AnApp < Padrino::Application; end
|
|
45
50
|
end
|
|
46
51
|
Padrino.mount("some_namespace/an_app").to("/")
|
|
47
52
|
assert_equal SomeNamespace::AnApp, Padrino.mounted_apps.first.app_obj
|
|
48
|
-
assert_equal ["some_namespace/an_app"], Padrino.mounted_apps.
|
|
53
|
+
assert_equal ["some_namespace/an_app"], Padrino.mounted_apps.map(&:name)
|
|
49
54
|
end
|
|
50
55
|
|
|
51
56
|
should 'mount a primary app to root uri' do
|
|
@@ -91,7 +96,7 @@ class TestMounter < Test::Unit::TestCase
|
|
|
91
96
|
assert_equal OneApp, Padrino.mounted_apps[0].app_obj
|
|
92
97
|
assert_equal TwoApp, Padrino.mounted_apps[1].app_obj
|
|
93
98
|
assert_equal 2, Padrino.mounted_apps.size, "should not mount duplicate apps"
|
|
94
|
-
assert_equal ["one_app", "two_app"], Padrino.mounted_apps.
|
|
99
|
+
assert_equal ["one_app", "two_app"], Padrino.mounted_apps.map(&:name)
|
|
95
100
|
end
|
|
96
101
|
|
|
97
102
|
should 'change mounted_root' do
|
|
@@ -9,8 +9,8 @@ class TestComplexReloader < Test::Unit::TestCase
|
|
|
9
9
|
Padrino.mounted_apps.clear
|
|
10
10
|
Padrino.mount("complex_1_demo").to("/complex_1_demo")
|
|
11
11
|
Padrino.mount("complex_2_demo").to("/complex_2_demo")
|
|
12
|
-
assert_equal ["/complex_1_demo", "/complex_2_demo"], Padrino.mounted_apps.
|
|
13
|
-
assert_equal ["complex_1_demo", "complex_2_demo"], Padrino.mounted_apps.
|
|
12
|
+
assert_equal ["/complex_1_demo", "/complex_2_demo"], Padrino.mounted_apps.map(&:uri_root)
|
|
13
|
+
assert_equal ["complex_1_demo", "complex_2_demo"], Padrino.mounted_apps.map(&:name)
|
|
14
14
|
assert Complex1Demo.reload?
|
|
15
15
|
assert Complex2Demo.reload?
|
|
16
16
|
assert_match %r{fixtures/apps/complex.rb}, Complex1Demo.app_file
|
|
@@ -39,26 +39,28 @@ class TestComplexReloader < Test::Unit::TestCase
|
|
|
39
39
|
new_phrase = "The magick number is: #{rand(100)}!"
|
|
40
40
|
buffer = File.read(Complex1Demo.app_file)
|
|
41
41
|
new_buffer = buffer.gsub(/The magick number is: \d+!/, new_phrase)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
begin
|
|
43
|
+
File.open(Complex1Demo.app_file, "w") { |f| f.write(new_buffer) }
|
|
44
|
+
sleep 1.2 # We need at least a cooldown of 1 sec.
|
|
45
|
+
get "/complex_2_demo"
|
|
46
|
+
assert_equal new_phrase, body
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
get "/complex_2_demo"
|
|
52
|
-
assert_equal 200, status
|
|
48
|
+
# Re-Check that we didn't forget any route
|
|
49
|
+
get "/complex_1_demo"
|
|
50
|
+
assert_equal "Given random #{LibDemo.give_me_a_random}", body
|
|
53
51
|
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
get "/complex_2_demo"
|
|
53
|
+
assert_equal 200, status
|
|
56
54
|
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
get "/complex_1_demo/old"
|
|
56
|
+
assert_equal 200, status
|
|
59
57
|
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
get "/complex_2_demo/old"
|
|
59
|
+
assert_equal 200, status
|
|
60
|
+
ensure
|
|
61
|
+
# Now we need to prevent to commit a new changed file so we revert it
|
|
62
|
+
File.open(Complex1Demo.app_file, "w") { |f| f.write(buffer) }
|
|
63
|
+
end
|
|
62
64
|
end
|
|
63
65
|
end
|
|
64
66
|
end
|
|
@@ -47,7 +47,7 @@ class TestSimpleReloader < Test::Unit::TestCase
|
|
|
47
47
|
should 'correctly instantiate SimpleDemo fixture' do
|
|
48
48
|
Padrino.mounted_apps.clear
|
|
49
49
|
Padrino.mount("simple_demo").to("/")
|
|
50
|
-
assert_equal ["simple_demo"], Padrino.mounted_apps.
|
|
50
|
+
assert_equal ["simple_demo"], Padrino.mounted_apps.map(&:name)
|
|
51
51
|
assert SimpleDemo.reload?
|
|
52
52
|
assert_match %r{fixtures/apps/simple.rb}, SimpleDemo.app_file
|
|
53
53
|
end
|
|
@@ -71,6 +71,7 @@ class TestSimpleReloader < Test::Unit::TestCase
|
|
|
71
71
|
|
|
72
72
|
should 'correctly reset SimpleDemo fixture' do
|
|
73
73
|
@app = SimpleDemo
|
|
74
|
+
@app.reload!
|
|
74
75
|
get "/rand"
|
|
75
76
|
assert ok?
|
|
76
77
|
last_body = body
|
data/test/test_router.rb
CHANGED
|
@@ -106,8 +106,8 @@ class TestRouter < Test::Unit::TestCase
|
|
|
106
106
|
should "works with padrino core applications" do
|
|
107
107
|
Padrino.mounted_apps.clear
|
|
108
108
|
Padrino.mount("simple_demo").host("padrino.org")
|
|
109
|
-
assert_equal ["simple_demo"], Padrino.mounted_apps.
|
|
110
|
-
assert_equal ["padrino.org"], Padrino.mounted_apps.
|
|
109
|
+
assert_equal ["simple_demo"], Padrino.mounted_apps.map(&:name)
|
|
110
|
+
assert_equal ["padrino.org"], Padrino.mounted_apps.map(&:app_host)
|
|
111
111
|
|
|
112
112
|
res = Rack::MockRequest.new(Padrino.application).get("/")
|
|
113
113
|
assert res.not_found?
|
data/test/test_routing.rb
CHANGED
|
@@ -4,11 +4,6 @@ class FooError < RuntimeError; end
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class TestRouting < Test::Unit::TestCase
|
|
7
|
-
should 'use padrinos url method' do
|
|
8
|
-
mock_app { }
|
|
9
|
-
assert_equal @app.method(:url).owner, Padrino::Routing::ClassMethods
|
|
10
|
-
end
|
|
11
|
-
|
|
12
7
|
should 'ignore trailing delimiters for basic route' do
|
|
13
8
|
mock_app do
|
|
14
9
|
get("/foo"){ "okey" }
|
|
@@ -35,23 +30,6 @@ class TestRouting < Test::Unit::TestCase
|
|
|
35
30
|
}
|
|
36
31
|
end
|
|
37
32
|
|
|
38
|
-
should_eventually 'generate a url using route string with params' do
|
|
39
|
-
mock_app do
|
|
40
|
-
get("/show/:id/:name"){ "okey" }
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
assert_equal "/show/1/foo", @app.url_for("/show/:id/:name", :id => 1, :name => "foo")
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
should 'work correctly with sinatra redirects' do
|
|
47
|
-
mock_app do
|
|
48
|
-
get(:index){ redirect url(:index) }
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
get "/"
|
|
52
|
-
assert_equal "http://example.org/", headers['Location']
|
|
53
|
-
end
|
|
54
|
-
|
|
55
33
|
should 'accept regexp routes' do
|
|
56
34
|
mock_app do
|
|
57
35
|
get(%r{/fob|/baz}) { "regexp" }
|
|
@@ -128,7 +106,7 @@ class TestRouting < Test::Unit::TestCase
|
|
|
128
106
|
assert_equal ["POST"], app.routes[2].as_options[:conditions][:request_method]
|
|
129
107
|
end
|
|
130
108
|
|
|
131
|
-
should 'generate basic urls'do
|
|
109
|
+
should 'generate basic urls' do
|
|
132
110
|
mock_app do
|
|
133
111
|
get(:foo){ "/foo" }
|
|
134
112
|
get(:foo, :with => :id){ |id| "/foo/#{id}" }
|
|
@@ -252,6 +230,31 @@ class TestRouting < Test::Unit::TestCase
|
|
|
252
230
|
assert_equal 'json', body
|
|
253
231
|
end
|
|
254
232
|
|
|
233
|
+
should "send the appropriate number of params" do
|
|
234
|
+
mock_app do
|
|
235
|
+
get('/id/:user_id', :provides => [:json]) { |user_id| user_id}
|
|
236
|
+
end
|
|
237
|
+
get '/id/5.json'
|
|
238
|
+
assert_equal '5', body
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
should "allow .'s in param values" do
|
|
242
|
+
mock_app do
|
|
243
|
+
get('/id/:email', :provides => [:json]) { |email, format| [email, format] * '/' }
|
|
244
|
+
end
|
|
245
|
+
get '/id/foo@bar.com.json'
|
|
246
|
+
assert_equal 'foo@bar.com/json', body
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
should "set correct content_type for Accept not equal to */* even if */* also provided" do
|
|
250
|
+
mock_app do
|
|
251
|
+
get("/foo", :provides => [:html, :js, :xml]) { content_type.to_s }
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
get '/foo', {}, { 'HTTP_ACCEPT' => 'application/javascript, */*;q=0.5' }
|
|
255
|
+
assert_equal 'js', body
|
|
256
|
+
end
|
|
257
|
+
|
|
255
258
|
should "return the first content type in provides if accept header is empty" do
|
|
256
259
|
mock_app do
|
|
257
260
|
get(:a, :provides => [:js]){ content_type.to_s }
|
|
@@ -326,7 +329,7 @@ class TestRouting < Test::Unit::TestCase
|
|
|
326
329
|
should "should inject the route into the request" do
|
|
327
330
|
mock_app do
|
|
328
331
|
controller :posts do
|
|
329
|
-
get(:index) { request.
|
|
332
|
+
get(:index) { request.route_obj.named.to_s }
|
|
330
333
|
end
|
|
331
334
|
end
|
|
332
335
|
get "/posts"
|
|
@@ -863,6 +866,14 @@ class TestRouting < Test::Unit::TestCase
|
|
|
863
866
|
assert_equal 'html', body
|
|
864
867
|
end
|
|
865
868
|
|
|
869
|
+
should "set content_type to :js if Accept includes both application/javascript and */*;q=0.5" do
|
|
870
|
+
mock_app do
|
|
871
|
+
get("/foo", :provides => [:html, :js]) { content_type.to_s }
|
|
872
|
+
end
|
|
873
|
+
get '/foo', {}, { 'HTTP_ACCEPT' => 'application/javascript, */*;q=0.5' }
|
|
874
|
+
assert_equal 'js', body
|
|
875
|
+
end
|
|
876
|
+
|
|
866
877
|
should 'allows custom route-conditions to be set via route options and halt' do
|
|
867
878
|
protector = Module.new do
|
|
868
879
|
def protect(*args)
|
|
@@ -1132,7 +1143,6 @@ class TestRouting < Test::Unit::TestCase
|
|
|
1132
1143
|
assert_equal "This is the get index.json", body
|
|
1133
1144
|
get "/.js"
|
|
1134
1145
|
assert_equal 404, status
|
|
1135
|
-
assert_match "Sinatra doesn't know this ditty", body
|
|
1136
1146
|
post "/.json"
|
|
1137
1147
|
assert_equal "This is the post index.json", body
|
|
1138
1148
|
post "/.js"
|
|
@@ -1330,4 +1340,39 @@ class TestRouting < Test::Unit::TestCase
|
|
|
1330
1340
|
assert_equal 200, status
|
|
1331
1341
|
assert_equal 'okay', body
|
|
1332
1342
|
end
|
|
1343
|
+
|
|
1344
|
+
should 'parse nested params' do
|
|
1345
|
+
mock_app do
|
|
1346
|
+
get(:index) { params.inspect }
|
|
1347
|
+
end
|
|
1348
|
+
get "/?account[name]=foo&account[surname]=bar"
|
|
1349
|
+
assert_equal '{"account"=>{"name"=>"foo", "surname"=>"bar"}}', body
|
|
1350
|
+
get @app.url(:index, "account[name]" => "foo", "account[surname]" => "bar")
|
|
1351
|
+
assert_equal '{"account"=>{"name"=>"foo", "surname"=>"bar"}}', body
|
|
1352
|
+
end
|
|
1353
|
+
|
|
1354
|
+
should 'render sinatra NotFound page' do
|
|
1355
|
+
mock_app { set :environment, :development }
|
|
1356
|
+
get "/"
|
|
1357
|
+
assert_equal 404, status
|
|
1358
|
+
assert_match /Sinatra doesn\'t know this ditty./, body
|
|
1359
|
+
end
|
|
1360
|
+
|
|
1361
|
+
should 'render a custom NotFound page' do
|
|
1362
|
+
mock_app do
|
|
1363
|
+
error(Sinatra::NotFound) { "not found" }
|
|
1364
|
+
end
|
|
1365
|
+
get "/"
|
|
1366
|
+
assert_equal 404, status
|
|
1367
|
+
assert_match /not found/, body
|
|
1368
|
+
end
|
|
1369
|
+
|
|
1370
|
+
should 'render a custom 404 page' do
|
|
1371
|
+
mock_app do
|
|
1372
|
+
error(404) { "not found" }
|
|
1373
|
+
end
|
|
1374
|
+
get "/"
|
|
1375
|
+
assert_equal 404, status
|
|
1376
|
+
assert_match /not found/, body
|
|
1377
|
+
end
|
|
1333
1378
|
end
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: padrino-core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
hash:
|
|
4
|
+
hash: 9
|
|
5
5
|
prerelease:
|
|
6
6
|
segments:
|
|
7
7
|
- 0
|
|
8
8
|
- 9
|
|
9
|
-
-
|
|
10
|
-
version: 0.9.
|
|
9
|
+
- 25
|
|
10
|
+
version: 0.9.25
|
|
11
11
|
platform: ruby
|
|
12
12
|
authors:
|
|
13
13
|
- Padrino Team
|
|
@@ -18,45 +18,61 @@ autorequire:
|
|
|
18
18
|
bindir: bin
|
|
19
19
|
cert_chain: []
|
|
20
20
|
|
|
21
|
-
date: 2011-04-
|
|
21
|
+
date: 2011-04-27 00:00:00 +02:00
|
|
22
22
|
default_executable: padrino
|
|
23
23
|
dependencies:
|
|
24
24
|
- !ruby/object:Gem::Dependency
|
|
25
|
-
name:
|
|
25
|
+
name: tilt
|
|
26
26
|
prerelease: false
|
|
27
27
|
requirement: &id001 !ruby/object:Gem::Requirement
|
|
28
28
|
none: false
|
|
29
29
|
requirements:
|
|
30
30
|
- - ~>
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
hash:
|
|
32
|
+
hash: 27
|
|
33
33
|
segments:
|
|
34
34
|
- 1
|
|
35
|
-
-
|
|
35
|
+
- 3
|
|
36
36
|
- 0
|
|
37
|
-
version: 1.
|
|
37
|
+
version: 1.3.0
|
|
38
38
|
type: :runtime
|
|
39
39
|
version_requirements: *id001
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
41
|
-
name:
|
|
41
|
+
name: sinatra
|
|
42
42
|
prerelease: false
|
|
43
43
|
requirement: &id002 !ruby/object:Gem::Requirement
|
|
44
44
|
none: false
|
|
45
45
|
requirements:
|
|
46
46
|
- - ~>
|
|
47
47
|
- !ruby/object:Gem::Version
|
|
48
|
-
hash:
|
|
48
|
+
hash: 25
|
|
49
|
+
segments:
|
|
50
|
+
- 1
|
|
51
|
+
- 2
|
|
52
|
+
- 3
|
|
53
|
+
version: 1.2.3
|
|
54
|
+
type: :runtime
|
|
55
|
+
version_requirements: *id002
|
|
56
|
+
- !ruby/object:Gem::Dependency
|
|
57
|
+
name: http_router
|
|
58
|
+
prerelease: false
|
|
59
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
|
60
|
+
none: false
|
|
61
|
+
requirements:
|
|
62
|
+
- - ~>
|
|
63
|
+
- !ruby/object:Gem::Version
|
|
64
|
+
hash: 11
|
|
49
65
|
segments:
|
|
50
66
|
- 0
|
|
51
|
-
-
|
|
67
|
+
- 7
|
|
52
68
|
- 4
|
|
53
|
-
version: 0.
|
|
69
|
+
version: 0.7.4
|
|
54
70
|
type: :runtime
|
|
55
|
-
version_requirements: *
|
|
71
|
+
version_requirements: *id003
|
|
56
72
|
- !ruby/object:Gem::Dependency
|
|
57
73
|
name: thor
|
|
58
74
|
prerelease: false
|
|
59
|
-
requirement: &
|
|
75
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
|
60
76
|
none: false
|
|
61
77
|
requirements:
|
|
62
78
|
- - ">="
|
|
@@ -68,11 +84,11 @@ dependencies:
|
|
|
68
84
|
- 3
|
|
69
85
|
version: 0.14.3
|
|
70
86
|
type: :runtime
|
|
71
|
-
version_requirements: *
|
|
87
|
+
version_requirements: *id004
|
|
72
88
|
- !ruby/object:Gem::Dependency
|
|
73
89
|
name: activesupport
|
|
74
90
|
prerelease: false
|
|
75
|
-
requirement: &
|
|
91
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
|
76
92
|
none: false
|
|
77
93
|
requirements:
|
|
78
94
|
- - ">="
|
|
@@ -84,11 +100,11 @@ dependencies:
|
|
|
84
100
|
- 0
|
|
85
101
|
version: 3.0.0
|
|
86
102
|
type: :runtime
|
|
87
|
-
version_requirements: *
|
|
103
|
+
version_requirements: *id005
|
|
88
104
|
- !ruby/object:Gem::Dependency
|
|
89
105
|
name: tzinfo
|
|
90
106
|
prerelease: false
|
|
91
|
-
requirement: &
|
|
107
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
|
92
108
|
none: false
|
|
93
109
|
requirements:
|
|
94
110
|
- - ">="
|
|
@@ -98,7 +114,7 @@ dependencies:
|
|
|
98
114
|
- 0
|
|
99
115
|
version: "0"
|
|
100
116
|
type: :runtime
|
|
101
|
-
version_requirements: *
|
|
117
|
+
version_requirements: *id006
|
|
102
118
|
description: The Padrino core gem required for use of this framework
|
|
103
119
|
email: padrinorb@gmail.com
|
|
104
120
|
executables:
|