sinatra-sinatra 0.9.0.4 → 0.9.0.5
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/AUTHORS +1 -1
- data/CHANGES +44 -0
- data/README.rdoc +12 -0
- data/Rakefile +2 -1
- data/compat/app_test.rb +3 -2
- data/compat/compat_test.rb +12 -0
- data/lib/sinatra/base.rb +206 -114
- data/lib/sinatra/compat.rb +18 -16
- data/lib/sinatra/main.rb +4 -4
- data/lib/sinatra/test.rb +10 -8
- data/sinatra.gemspec +7 -2
- data/test/base_test.rb +13 -0
- data/test/extensions_test.rb +63 -0
- data/test/helper.rb +13 -2
- data/test/helpers_test.rb +58 -0
- data/test/mapped_error_test.rb +6 -6
- data/test/middleware_test.rb +3 -1
- data/test/response_test.rb +42 -0
- data/test/routing_test.rb +166 -0
- data/test/server_test.rb +41 -0
- data/test/static_test.rb +8 -10
- data/test/test_test.rb +21 -0
- metadata +11 -2
data/lib/sinatra/base.rb
CHANGED
@@ -1,18 +1,21 @@
|
|
1
|
+
require 'thread'
|
1
2
|
require 'time'
|
2
3
|
require 'uri'
|
3
4
|
require 'rack'
|
4
5
|
require 'rack/builder'
|
5
6
|
|
6
7
|
module Sinatra
|
7
|
-
VERSION = '0.9.0.
|
8
|
+
VERSION = '0.9.0.5'
|
8
9
|
|
10
|
+
# The request object. See Rack::Request for more info:
|
11
|
+
# http://rack.rubyforge.org/doc/classes/Rack/Request.html
|
9
12
|
class Request < Rack::Request
|
10
13
|
def user_agent
|
11
14
|
@env['HTTP_USER_AGENT']
|
12
15
|
end
|
13
16
|
|
14
17
|
def accept
|
15
|
-
@env['HTTP_ACCEPT'].split(',').map { |a| a.strip }
|
18
|
+
@env['HTTP_ACCEPT'].to_s.split(',').map { |a| a.strip }
|
16
19
|
end
|
17
20
|
|
18
21
|
# Override Rack 0.9.x's #params implementation (see #72 in lighthouse)
|
@@ -23,6 +26,10 @@ module Sinatra
|
|
23
26
|
end
|
24
27
|
end
|
25
28
|
|
29
|
+
# The response object. See Rack::Response and Rack::ResponseHelpers for
|
30
|
+
# more info:
|
31
|
+
# http://rack.rubyforge.org/doc/classes/Rack/Response.html
|
32
|
+
# http://rack.rubyforge.org/doc/classes/Rack/Response/Helpers.html
|
26
33
|
class Response < Rack::Response
|
27
34
|
def initialize
|
28
35
|
@status, @body = 200, []
|
@@ -44,17 +51,18 @@ module Sinatra
|
|
44
51
|
body = [body] if body.respond_to? :to_str
|
45
52
|
if header["Content-Length"].nil? && body.respond_to?(:to_ary)
|
46
53
|
header["Content-Length"] = body.to_ary.
|
47
|
-
inject(0) { |len, part| len + part.
|
54
|
+
inject(0) { |len, part| len + part.bytesize }.to_s
|
48
55
|
end
|
49
56
|
[status.to_i, header.to_hash, body]
|
50
57
|
end
|
51
58
|
end
|
52
59
|
end
|
53
60
|
|
54
|
-
class NotFound < NameError
|
61
|
+
class NotFound < NameError #:nodoc:
|
55
62
|
def code ; 404 ; end
|
56
63
|
end
|
57
64
|
|
65
|
+
# Methods available to routes, before filters, and views.
|
58
66
|
module Helpers
|
59
67
|
# Set or retrieve the response status code.
|
60
68
|
def status(value=nil)
|
@@ -82,7 +90,7 @@ module Sinatra
|
|
82
90
|
|
83
91
|
# Halt processing and return the error status provided.
|
84
92
|
def error(code, body=nil)
|
85
|
-
code, body
|
93
|
+
code, body = 500, code.to_str if code.respond_to? :to_str
|
86
94
|
response.body = body unless body.nil?
|
87
95
|
halt code
|
88
96
|
end
|
@@ -194,11 +202,42 @@ module Sinatra
|
|
194
202
|
halt 304 if etags.include?(value) || etags.include?('*')
|
195
203
|
end
|
196
204
|
end
|
205
|
+
|
206
|
+
## Sugar for redirect (example: redirect back)
|
207
|
+
def back ; request.referer ; end
|
208
|
+
|
197
209
|
end
|
198
210
|
|
211
|
+
# Template rendering methods. Each method takes a the name of a template
|
212
|
+
# to render as a Symbol and returns a String with the rendered output.
|
199
213
|
module Templates
|
200
|
-
def
|
201
|
-
|
214
|
+
def erb(template, options={})
|
215
|
+
require 'erb' unless defined? ::ERB
|
216
|
+
render :erb, template, options
|
217
|
+
end
|
218
|
+
|
219
|
+
def haml(template, options={})
|
220
|
+
require 'haml' unless defined? ::Haml
|
221
|
+
options[:options] ||= self.class.haml if self.class.respond_to? :haml
|
222
|
+
render :haml, template, options
|
223
|
+
end
|
224
|
+
|
225
|
+
def sass(template, options={}, &block)
|
226
|
+
require 'sass' unless defined? ::Sass
|
227
|
+
options[:layout] = false
|
228
|
+
render :sass, template, options
|
229
|
+
end
|
230
|
+
|
231
|
+
def builder(template=nil, options={}, &block)
|
232
|
+
require 'builder' unless defined? ::Builder
|
233
|
+
options, template = template, nil if template.is_a?(Hash)
|
234
|
+
template = lambda { block } if template.nil?
|
235
|
+
render :builder, template, options
|
236
|
+
end
|
237
|
+
|
238
|
+
private
|
239
|
+
def render(engine, template, options={}) #:nodoc:
|
240
|
+
data = lookup_template(engine, template, options)
|
202
241
|
output = __send__("render_#{engine}", template, data, options)
|
203
242
|
layout, data = lookup_layout(engine, options)
|
204
243
|
if layout
|
@@ -229,7 +268,7 @@ module Sinatra
|
|
229
268
|
return if options[:layout] == false
|
230
269
|
options.delete(:layout) if options[:layout] == true
|
231
270
|
template = options[:layout] || :layout
|
232
|
-
data
|
271
|
+
data = lookup_template(engine, template, options)
|
233
272
|
[template, data]
|
234
273
|
rescue Errno::ENOENT
|
235
274
|
nil
|
@@ -241,11 +280,6 @@ module Sinatra
|
|
241
280
|
"#{views_dir}/#{template}.#{engine}"
|
242
281
|
end
|
243
282
|
|
244
|
-
def erb(template, options={})
|
245
|
-
require 'erb' unless defined? ::ERB
|
246
|
-
render :erb, template, options
|
247
|
-
end
|
248
|
-
|
249
283
|
def render_erb(template, data, options, &block)
|
250
284
|
data = data.call if data.kind_of? Proc
|
251
285
|
instance = ::ERB.new(data)
|
@@ -253,13 +287,6 @@ module Sinatra
|
|
253
287
|
locals_assigns = locals.to_a.collect { |k,v| "#{k} = locals[:#{k}]" }
|
254
288
|
src = "#{locals_assigns.join("\n")}\n#{instance.src}"
|
255
289
|
eval src, binding, '(__ERB__)', locals_assigns.length + 1
|
256
|
-
instance.result(binding)
|
257
|
-
end
|
258
|
-
|
259
|
-
def haml(template, options={})
|
260
|
-
require 'haml' unless defined? ::Haml
|
261
|
-
options[:options] ||= self.class.haml if self.class.respond_to? :haml
|
262
|
-
render :haml, template, options
|
263
290
|
end
|
264
291
|
|
265
292
|
def render_haml(template, data, options, &block)
|
@@ -267,24 +294,11 @@ module Sinatra
|
|
267
294
|
engine.render(self, options[:locals] || {}, &block)
|
268
295
|
end
|
269
296
|
|
270
|
-
def sass(template, options={}, &block)
|
271
|
-
require 'sass' unless defined? ::Sass
|
272
|
-
options[:layout] = false
|
273
|
-
render :sass, template, options
|
274
|
-
end
|
275
|
-
|
276
297
|
def render_sass(template, data, options, &block)
|
277
298
|
engine = ::Sass::Engine.new(data, options[:sass] || {})
|
278
299
|
engine.render
|
279
300
|
end
|
280
301
|
|
281
|
-
def builder(template=nil, options={}, &block)
|
282
|
-
require 'builder' unless defined? ::Builder
|
283
|
-
options, template = template, nil if template.is_a?(Hash)
|
284
|
-
template = lambda { block } if template.nil?
|
285
|
-
render :builder, template, options
|
286
|
-
end
|
287
|
-
|
288
302
|
def render_builder(template, data, options, &block)
|
289
303
|
xml = ::Builder::XmlMarkup.new(:indent => 2)
|
290
304
|
if data.respond_to?(:to_str)
|
@@ -294,9 +308,9 @@ module Sinatra
|
|
294
308
|
end
|
295
309
|
xml.target!
|
296
310
|
end
|
297
|
-
|
298
311
|
end
|
299
312
|
|
313
|
+
# Base class for all Sinatra applications and middleware.
|
300
314
|
class Base
|
301
315
|
include Rack::Utils
|
302
316
|
include Helpers
|
@@ -309,6 +323,7 @@ module Sinatra
|
|
309
323
|
yield self if block_given?
|
310
324
|
end
|
311
325
|
|
326
|
+
# Rack call interface.
|
312
327
|
def call(env)
|
313
328
|
dup.call!(env)
|
314
329
|
end
|
@@ -324,19 +339,24 @@ module Sinatra
|
|
324
339
|
invoke { dispatch! }
|
325
340
|
invoke { error_block!(response.status) }
|
326
341
|
|
342
|
+
# never respond with a body on HEAD requests
|
327
343
|
@response.body = [] if @env['REQUEST_METHOD'] == 'HEAD'
|
344
|
+
|
328
345
|
@response.finish
|
329
346
|
end
|
330
347
|
|
348
|
+
# Access options defined with Base.set.
|
331
349
|
def options
|
332
350
|
self.class
|
333
351
|
end
|
334
352
|
|
353
|
+
# Exit the current block and halt the response.
|
335
354
|
def halt(*response)
|
336
355
|
response = response.first if response.length == 1
|
337
356
|
throw :halt, response
|
338
357
|
end
|
339
358
|
|
359
|
+
# Pass control to the next matching route.
|
340
360
|
def pass
|
341
361
|
throw :pass
|
342
362
|
end
|
@@ -352,7 +372,7 @@ module Sinatra
|
|
352
372
|
# routes
|
353
373
|
if routes = self.class.routes[@request.request_method]
|
354
374
|
original_params = @params
|
355
|
-
path
|
375
|
+
path = @request.path_info
|
356
376
|
|
357
377
|
routes.each do |pattern, keys, conditions, block|
|
358
378
|
if match = pattern.match(path)
|
@@ -373,6 +393,7 @@ module Sinatra
|
|
373
393
|
{}
|
374
394
|
end
|
375
395
|
@params = original_params.merge(params)
|
396
|
+
@block_params = values
|
376
397
|
|
377
398
|
catch(:pass) do
|
378
399
|
conditions.each { |cond|
|
@@ -389,10 +410,10 @@ module Sinatra
|
|
389
410
|
def nested_params(params)
|
390
411
|
return indifferent_hash.merge(params) if !params.keys.join.include?('[')
|
391
412
|
params.inject indifferent_hash do |res, (key,val)|
|
392
|
-
if key
|
393
|
-
|
394
|
-
|
395
|
-
head.inject(res){ |
|
413
|
+
if key.include?('[')
|
414
|
+
head = key.split(/[\]\[]+/)
|
415
|
+
last = head.pop
|
416
|
+
head.inject(res){ |hash,k| hash[k] ||= indifferent_hash }[last] = val
|
396
417
|
else
|
397
418
|
res[key] = val
|
398
419
|
end
|
@@ -421,7 +442,7 @@ module Sinatra
|
|
421
442
|
headers.each { |k, v| @response.headers[k] = v } if headers
|
422
443
|
elsif res.length == 2
|
423
444
|
@response.status = res.first
|
424
|
-
@response.body
|
445
|
+
@response.body = res.last
|
425
446
|
else
|
426
447
|
raise TypeError, "#{res.inspect} not supported"
|
427
448
|
end
|
@@ -441,21 +462,24 @@ module Sinatra
|
|
441
462
|
def dispatch!
|
442
463
|
route!
|
443
464
|
rescue NotFound => boom
|
465
|
+
handle_not_found!(boom)
|
466
|
+
rescue ::Exception => boom
|
467
|
+
handle_exception!(boom)
|
468
|
+
end
|
469
|
+
|
470
|
+
def handle_not_found!(boom)
|
444
471
|
@env['sinatra.error'] = boom
|
445
|
-
@response.status
|
446
|
-
@response.body
|
472
|
+
@response.status = 404
|
473
|
+
@response.body = ['<h1>Not Found</h1>']
|
447
474
|
error_block! boom.class, NotFound
|
475
|
+
end
|
448
476
|
|
449
|
-
|
477
|
+
def handle_exception!(boom)
|
450
478
|
@env['sinatra.error'] = boom
|
451
479
|
|
452
|
-
if options.dump_errors?
|
453
|
-
|
454
|
-
msg = ["#{boom.class} - #{boom.message}:", *backtrace].join("\n ")
|
455
|
-
@env['rack.errors'].write(msg)
|
456
|
-
end
|
480
|
+
dump_errors!(boom) if options.dump_errors?
|
481
|
+
raise boom if options.raise_errors?
|
457
482
|
|
458
|
-
raise boom if options.raise_errors?
|
459
483
|
@response.status = 500
|
460
484
|
error_block! boom.class, Exception
|
461
485
|
end
|
@@ -472,6 +496,13 @@ module Sinatra
|
|
472
496
|
nil
|
473
497
|
end
|
474
498
|
|
499
|
+
def dump_errors!(boom)
|
500
|
+
backtrace = clean_backtrace(boom.backtrace)
|
501
|
+
msg = ["#{boom.class} - #{boom.message}:",
|
502
|
+
*backtrace].join("\n ")
|
503
|
+
@env['rack.errors'].write(msg)
|
504
|
+
end
|
505
|
+
|
475
506
|
def clean_backtrace(trace)
|
476
507
|
return trace unless options.clean_trace?
|
477
508
|
|
@@ -493,13 +524,14 @@ module Sinatra
|
|
493
524
|
attr_accessor :routes, :filters, :conditions, :templates,
|
494
525
|
:middleware, :errors
|
495
526
|
|
527
|
+
public
|
496
528
|
def set(option, value=self)
|
497
529
|
if value.kind_of?(Proc)
|
498
530
|
metadef(option, &value)
|
499
531
|
metadef("#{option}?") { !!__send__(option) }
|
500
532
|
metadef("#{option}=") { |val| set(option, Proc.new{val}) }
|
501
533
|
elsif value == self && option.respond_to?(:to_hash)
|
502
|
-
option.to_hash.each(
|
534
|
+
option.to_hash.each { |k,v| set(k, v) }
|
503
535
|
elsif respond_to?("#{option}=")
|
504
536
|
__send__ "#{option}=", value
|
505
537
|
else
|
@@ -537,14 +569,10 @@ module Sinatra
|
|
537
569
|
end
|
538
570
|
|
539
571
|
def use_in_file_templates!
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
/rubygems\/custom_require\.rb/
|
545
|
-
].all? { |x| s !~ x }
|
546
|
-
end
|
547
|
-
file = line.sub(/:\d+.*$/, '')
|
572
|
+
ignore = [/lib\/sinatra.*\.rb/, /\(.*\)/, /rubygems\/custom_require\.rb/]
|
573
|
+
file = caller.
|
574
|
+
map { |line| line.sub(/:\d+.*$/, '') }.
|
575
|
+
find { |line| ignore.all? { |pattern| line !~ pattern } }
|
548
576
|
if data = ::IO.read(file).split('__END__')[1]
|
549
577
|
data.gsub!(/\r\n/, "\n")
|
550
578
|
template = nil
|
@@ -573,6 +601,7 @@ module Sinatra
|
|
573
601
|
@conditions << block
|
574
602
|
end
|
575
603
|
|
604
|
+
private
|
576
605
|
def host_name(pattern)
|
577
606
|
condition { pattern === request.host }
|
578
607
|
end
|
@@ -603,6 +632,7 @@ module Sinatra
|
|
603
632
|
}
|
604
633
|
end
|
605
634
|
|
635
|
+
public
|
606
636
|
def get(path, opts={}, &block)
|
607
637
|
conditions = @conditions.dup
|
608
638
|
route('GET', path, opts, &block)
|
@@ -627,7 +657,12 @@ module Sinatra
|
|
627
657
|
|
628
658
|
define_method "#{verb} #{path}", &block
|
629
659
|
unbound_method = instance_method("#{verb} #{path}")
|
630
|
-
block =
|
660
|
+
block =
|
661
|
+
if block.arity != 0
|
662
|
+
lambda { unbound_method.bind(self).call(*@block_params) }
|
663
|
+
else
|
664
|
+
lambda { unbound_method.bind(self).call }
|
665
|
+
end
|
631
666
|
|
632
667
|
(routes[verb] ||= []).
|
633
668
|
push([pattern, keys, conditions, block]).last
|
@@ -659,11 +694,22 @@ module Sinatra
|
|
659
694
|
end
|
660
695
|
|
661
696
|
public
|
697
|
+
def helpers(*extensions, &block)
|
698
|
+
class_eval(&block) if block_given?
|
699
|
+
include *extensions
|
700
|
+
end
|
701
|
+
|
702
|
+
def register(*extensions, &block)
|
703
|
+
extensions << Module.new(&block) if block
|
704
|
+
extend *extensions
|
705
|
+
end
|
706
|
+
|
662
707
|
def development? ; environment == :development ; end
|
663
708
|
def test? ; environment == :test ; end
|
664
709
|
def production? ; environment == :production ; end
|
665
710
|
|
666
711
|
def configure(*envs, &block)
|
712
|
+
return if reloading?
|
667
713
|
yield if envs.empty? || envs.include?(environment.to_sym)
|
668
714
|
end
|
669
715
|
|
@@ -674,7 +720,7 @@ module Sinatra
|
|
674
720
|
|
675
721
|
def run!(options={})
|
676
722
|
set options
|
677
|
-
handler
|
723
|
+
handler = detect_rack_handler
|
678
724
|
handler_name = handler.name.gsub(/.*::/, '')
|
679
725
|
puts "== Sinatra/#{Sinatra::VERSION} has taken the stage " +
|
680
726
|
"on #{port} for #{environment} with backup from #{handler_name}"
|
@@ -690,8 +736,19 @@ module Sinatra
|
|
690
736
|
end
|
691
737
|
|
692
738
|
def call(env)
|
693
|
-
|
694
|
-
|
739
|
+
synchronize do
|
740
|
+
reload! if reload?
|
741
|
+
construct_middleware if @callsite.nil?
|
742
|
+
@callsite.call(env)
|
743
|
+
end
|
744
|
+
end
|
745
|
+
|
746
|
+
def reload!
|
747
|
+
@reloading = true
|
748
|
+
superclass.send :reset!, self
|
749
|
+
$LOADED_FEATURES.delete("sinatra.rb")
|
750
|
+
::Kernel.load app_file
|
751
|
+
@reloading = false
|
695
752
|
end
|
696
753
|
|
697
754
|
private
|
@@ -720,17 +777,34 @@ module Sinatra
|
|
720
777
|
@callsite = nil
|
721
778
|
end
|
722
779
|
|
723
|
-
def
|
724
|
-
subclass.routes
|
725
|
-
subclass.templates
|
780
|
+
def reset!(subclass = self)
|
781
|
+
subclass.routes = dupe_routes
|
782
|
+
subclass.templates = templates.dup
|
726
783
|
subclass.conditions = []
|
727
|
-
subclass.filters
|
728
|
-
subclass.errors
|
784
|
+
subclass.filters = filters.dup
|
785
|
+
subclass.errors = errors.dup
|
729
786
|
subclass.middleware = middleware.dup
|
730
787
|
subclass.send :reset_middleware
|
788
|
+
end
|
789
|
+
|
790
|
+
def inherited(subclass)
|
791
|
+
reset!(subclass)
|
731
792
|
super
|
732
793
|
end
|
733
794
|
|
795
|
+
def reloading?
|
796
|
+
@reloading ||= false
|
797
|
+
end
|
798
|
+
|
799
|
+
@@mutex = Mutex.new
|
800
|
+
def synchronize(&block)
|
801
|
+
if lock?
|
802
|
+
@@mutex.synchronize(&block)
|
803
|
+
else
|
804
|
+
yield
|
805
|
+
end
|
806
|
+
end
|
807
|
+
|
734
808
|
def dupe_routes
|
735
809
|
routes.inject({}) do |hash,(request_method,routes)|
|
736
810
|
hash[request_method] = routes.dup
|
@@ -762,6 +836,8 @@ module Sinatra
|
|
762
836
|
set :root, Proc.new { app_file && File.expand_path(File.dirname(app_file)) }
|
763
837
|
set :views, Proc.new { root && File.join(root, 'views') }
|
764
838
|
set :public, Proc.new { root && File.join(root, 'public') }
|
839
|
+
set :reload, Proc.new { app_file? && app_file !~ /\.ru$/i && development? }
|
840
|
+
set :lock, Proc.new { reload? }
|
765
841
|
|
766
842
|
# static files route
|
767
843
|
get(/.*[^\/]$/) do
|
@@ -838,6 +914,7 @@ module Sinatra
|
|
838
914
|
end
|
839
915
|
end
|
840
916
|
|
917
|
+
# Base class for classic style (top-level) applications.
|
841
918
|
class Default < Base
|
842
919
|
set :raise_errors, false
|
843
920
|
set :dump_errors, true
|
@@ -846,61 +923,35 @@ module Sinatra
|
|
846
923
|
set :methodoverride, true
|
847
924
|
set :static, true
|
848
925
|
set :run, false
|
849
|
-
set :reload, Proc.new { app_file? && app_file !~ /\.ru$/i && development? }
|
850
|
-
set :lock, Proc.new { reload? }
|
851
|
-
|
852
|
-
def self.reloading?
|
853
|
-
@reloading ||= false
|
854
|
-
end
|
855
|
-
|
856
|
-
def self.configure(*envs)
|
857
|
-
super unless reloading?
|
858
|
-
end
|
859
|
-
|
860
|
-
def self.call(env)
|
861
|
-
synchronize do
|
862
|
-
reload! if reload?
|
863
|
-
super
|
864
|
-
end
|
865
|
-
end
|
866
|
-
|
867
|
-
def self.reload!
|
868
|
-
@reloading = true
|
869
|
-
superclass.send :inherited, self
|
870
|
-
$LOADED_FEATURES.delete("sinatra.rb")
|
871
|
-
::Kernel.load app_file
|
872
|
-
@reloading = false
|
873
|
-
end
|
874
926
|
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
@@mutex.synchronize(&block)
|
880
|
-
else
|
881
|
-
yield
|
882
|
-
end
|
927
|
+
def self.register(*extensions, &block) #:nodoc:
|
928
|
+
added_methods = extensions.map {|m| m.public_instance_methods }.flatten
|
929
|
+
Delegator.delegate *added_methods
|
930
|
+
super(*extensions, &block)
|
883
931
|
end
|
884
932
|
end
|
885
933
|
|
934
|
+
# The top-level Application. All DSL methods executed on main are delegated
|
935
|
+
# to this class.
|
886
936
|
class Application < Default
|
887
937
|
end
|
888
938
|
|
889
|
-
module Delegator
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
::Sinatra::Application.#{method_name}(*args, &b)
|
900
|
-
end
|
901
|
-
private :#{method_name}
|
902
|
-
RUBY
|
939
|
+
module Delegator #:nodoc:
|
940
|
+
def self.delegate(*methods)
|
941
|
+
methods.each do |method_name|
|
942
|
+
eval <<-RUBY, binding, '(__DELEGATE__)', 1
|
943
|
+
def #{method_name}(*args, &b)
|
944
|
+
::Sinatra::Application.#{method_name}(*args, &b)
|
945
|
+
end
|
946
|
+
private :#{method_name}
|
947
|
+
RUBY
|
948
|
+
end
|
903
949
|
end
|
950
|
+
|
951
|
+
delegate :get, :put, :post, :delete, :head, :template, :layout, :before,
|
952
|
+
:error, :not_found, :configures, :configure, :set, :set_option,
|
953
|
+
:set_options, :enable, :disable, :use, :development?, :test?,
|
954
|
+
:production?, :use_in_file_templates!, :helpers
|
904
955
|
end
|
905
956
|
|
906
957
|
def self.new(base=Base, options={}, &block)
|
@@ -908,4 +959,45 @@ module Sinatra
|
|
908
959
|
base.send :class_eval, &block if block_given?
|
909
960
|
base
|
910
961
|
end
|
962
|
+
|
963
|
+
# Extend the top-level DSL with the modules provided.
|
964
|
+
def self.register(*extensions, &block)
|
965
|
+
Default.register(*extensions, &block)
|
966
|
+
end
|
967
|
+
|
968
|
+
# Include the helper modules provided in Sinatra's request context.
|
969
|
+
def self.helpers(*extensions, &block)
|
970
|
+
Default.helpers(*extensions, &block)
|
971
|
+
end
|
972
|
+
end
|
973
|
+
|
974
|
+
class String #:nodoc:
|
975
|
+
# Define String#each under 1.9 for Rack compatibility. This should be
|
976
|
+
# removed once Rack is fully 1.9 compatible.
|
977
|
+
alias_method :each, :each_line unless ''.respond_to? :each
|
978
|
+
|
979
|
+
# Define String#bytesize as an alias to String#length for Ruby 1.8.6 and
|
980
|
+
# earlier.
|
981
|
+
alias_method :bytesize, :length unless ''.respond_to? :bytesize
|
982
|
+
end
|
983
|
+
|
984
|
+
class Rack::Builder
|
985
|
+
## Sugar to include a classic style app in a rackup.
|
986
|
+
##
|
987
|
+
## This will eval the source into a Sinatra::Default class
|
988
|
+
## Example:
|
989
|
+
##
|
990
|
+
## require 'sinatra/base'
|
991
|
+
##
|
992
|
+
## map '/foo' do
|
993
|
+
## run Sinatra("foo.rb")
|
994
|
+
## end
|
995
|
+
##
|
996
|
+
## run Sinatra("bar.rb")
|
997
|
+
##
|
998
|
+
def Sinatra(file, base=Sinatra::Default)
|
999
|
+
Sinatra.new(base) {
|
1000
|
+
expanded = File.expand_path(file)
|
1001
|
+
self.class_eval(File.read(expanded), expanded) }
|
1002
|
+
end
|
911
1003
|
end
|
data/lib/sinatra/compat.rb
CHANGED
@@ -9,7 +9,7 @@ require 'sinatra/base'
|
|
9
9
|
require 'sinatra/main'
|
10
10
|
|
11
11
|
# Like Kernel#warn but outputs the location that triggered the warning.
|
12
|
-
def sinatra_warn(*message)
|
12
|
+
def sinatra_warn(*message) #:nodoc:
|
13
13
|
line = caller.
|
14
14
|
detect { |line| line !~ /(?:lib\/sinatra\/|__DELEGATE__)/ }.
|
15
15
|
sub(/:in .*/, '')
|
@@ -34,25 +34,27 @@ end
|
|
34
34
|
# technically a Sinatra issue but many Sinatra apps access the old
|
35
35
|
# MIME_TYPES constants due to Sinatra example code.
|
36
36
|
require 'rack/file'
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
37
|
+
module Rack #:nodoc:
|
38
|
+
class File #:nodoc:
|
39
|
+
def self.const_missing(const_name)
|
40
|
+
if const_name == :MIME_TYPES
|
41
|
+
hash = Hash.new { |hash,key| Rack::Mime::MIME_TYPES[".#{key}"] }
|
42
|
+
const_set :MIME_TYPES, hash
|
43
|
+
sinatra_warn 'Rack::File::MIME_TYPES is deprecated; use Rack::Mime instead.'
|
44
|
+
hash
|
45
|
+
else
|
46
|
+
super
|
47
|
+
end
|
46
48
|
end
|
47
49
|
end
|
48
50
|
end
|
49
51
|
|
50
52
|
module Sinatra
|
51
|
-
module Compat
|
53
|
+
module Compat #:nodoc:
|
52
54
|
end
|
53
55
|
|
54
56
|
# Make Sinatra::EventContext an alias for Sinatra::Default to unbreak plugins.
|
55
|
-
def self.const_missing(const_name)
|
57
|
+
def self.const_missing(const_name) #:nodoc:
|
56
58
|
if const_name == :EventContext
|
57
59
|
const_set :EventContext, Sinatra::Default
|
58
60
|
sinatra_warn 'Sinatra::EventContext is deprecated; use Sinatra::Default instead.'
|
@@ -73,7 +75,7 @@ module Sinatra
|
|
73
75
|
end
|
74
76
|
|
75
77
|
class Default < Base
|
76
|
-
def self.const_missing(const_name)
|
78
|
+
def self.const_missing(const_name) #:nodoc:
|
77
79
|
if const_name == :FORWARD_METHODS
|
78
80
|
sinatra_warn 'Sinatra::Application::FORWARD_METHODS is deprecated;',
|
79
81
|
'use Sinatra::Delegator::METHODS instead.'
|
@@ -107,7 +109,7 @@ module Sinatra
|
|
107
109
|
# Throwing halt with a Symbol and the to_result convention are
|
108
110
|
# deprecated. Override the invoke method to detect those types of return
|
109
111
|
# values.
|
110
|
-
def invoke(&block)
|
112
|
+
def invoke(&block) #:nodoc:
|
111
113
|
res = super
|
112
114
|
case
|
113
115
|
when res.kind_of?(Symbol)
|
@@ -121,7 +123,7 @@ module Sinatra
|
|
121
123
|
res
|
122
124
|
end
|
123
125
|
|
124
|
-
def options
|
126
|
+
def options #:nodoc:
|
125
127
|
Options.new(self.class)
|
126
128
|
end
|
127
129
|
|
@@ -184,7 +186,7 @@ module Sinatra
|
|
184
186
|
end
|
185
187
|
|
186
188
|
# Deprecated. Missing messages are no longer delegated to @response.
|
187
|
-
def method_missing(name, *args, &b)
|
189
|
+
def method_missing(name, *args, &b) #:nodoc:
|
188
190
|
if @response.respond_to?(name)
|
189
191
|
sinatra_warn "The '#{name}' method is deprecated; use 'response.#{name}' instead."
|
190
192
|
@response.send(name, *args, &b)
|
data/lib/sinatra/main.rb
CHANGED
@@ -2,6 +2,10 @@ require 'sinatra/base'
|
|
2
2
|
|
3
3
|
module Sinatra
|
4
4
|
class Default < Base
|
5
|
+
|
6
|
+
# we assume that the first file that requires 'sinatra' is the
|
7
|
+
# app_file. all other path related options are calculated based
|
8
|
+
# on this path by default.
|
5
9
|
set :app_file, lambda {
|
6
10
|
ignore = [
|
7
11
|
/lib\/sinatra.*\.rb$/, # all sinatra code
|
@@ -32,10 +36,6 @@ end
|
|
32
36
|
|
33
37
|
include Sinatra::Delegator
|
34
38
|
|
35
|
-
def helpers(&block)
|
36
|
-
Sinatra::Application.send :class_eval, &block
|
37
|
-
end
|
38
|
-
|
39
39
|
def mime(ext, type)
|
40
40
|
ext = ".#{ext}" unless ext.to_s[0] == ?.
|
41
41
|
Rack::Mime::MIME_TYPES[ext.to_s] = type
|