sinatra-sinatra 0.9.1.2 → 0.9.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -1
- data/README.rdoc +42 -0
- data/Rakefile +15 -3
- data/compat/haml_test.rb +7 -4
- data/compat/helper.rb +4 -0
- data/compat/sass_test.rb +10 -0
- data/lib/sinatra/base.rb +136 -121
- data/lib/sinatra/compat.rb +16 -0
- data/lib/sinatra/showexceptions.rb +303 -0
- data/sinatra.gemspec +11 -3
- data/test/base_test.rb +117 -101
- data/test/builder_test.rb +1 -1
- data/test/contest.rb +62 -0
- data/test/erb_test.rb +1 -1
- data/test/extensions_test.rb +1 -1
- data/test/filter_test.rb +1 -1
- data/test/haml_test.rb +25 -3
- data/test/helper.rb +14 -46
- data/test/helpers_test.rb +444 -442
- data/test/mapped_error_test.rb +147 -144
- data/test/middleware_test.rb +2 -2
- data/test/options_test.rb +247 -206
- data/test/render_backtrace_test.rb +145 -0
- data/test/request_test.rb +1 -1
- data/test/response_test.rb +2 -2
- data/test/result_test.rb +1 -1
- data/test/route_added_hook_test.rb +59 -0
- data/test/routing_test.rb +12 -1
- data/test/sass_test.rb +43 -1
- data/test/server_test.rb +5 -3
- data/test/sinatra_test.rb +1 -1
- data/test/static_test.rb +2 -2
- data/test/templates_test.rb +16 -4
- data/test/test_test.rb +5 -5
- data/test/views/error.builder +3 -0
- data/test/views/error.erb +3 -0
- data/test/views/error.haml +3 -0
- data/test/views/error.sass +2 -0
- metadata +12 -5
data/LICENSE
CHANGED
data/README.rdoc
CHANGED
@@ -109,18 +109,41 @@ directory. To use a different views directory:
|
|
109
109
|
|
110
110
|
set :views, File.dirname(__FILE__) + '/templates'
|
111
111
|
|
112
|
+
One important thing to remember is that you always have to reference
|
113
|
+
templates with symbols, even if they're in a subdirectory (in this
|
114
|
+
case use <tt>:'subdir/template'</tt>). Rendering methods will render
|
115
|
+
any strings passed to them directly.
|
116
|
+
|
112
117
|
=== Haml Templates
|
113
118
|
|
114
119
|
The haml gem/library is required to render HAML templates:
|
115
120
|
|
121
|
+
## You'll need to require haml in your app
|
122
|
+
require 'haml'
|
123
|
+
|
116
124
|
get '/' do
|
117
125
|
haml :index
|
118
126
|
end
|
119
127
|
|
120
128
|
Renders <tt>./views/index.haml</tt>.
|
121
129
|
|
130
|
+
{Haml's options}[http://haml.hamptoncatlin.com/docs/rdoc/classes/Haml.html]
|
131
|
+
can be set globally through Sinatra's configurations,
|
132
|
+
see {Options and Configurations}[http://www.sinatrarb.com/configuration.html],
|
133
|
+
and overridden on an individual basis.
|
134
|
+
|
135
|
+
set :haml, {:format => :html5 } # default Haml format is :xhtml
|
136
|
+
|
137
|
+
get '/' do
|
138
|
+
haml :index, :haml_options => {:format => :html4 } # overridden
|
139
|
+
end
|
140
|
+
|
141
|
+
|
122
142
|
=== Erb Templates
|
123
143
|
|
144
|
+
## You'll need to require erb in your app
|
145
|
+
require 'erb'
|
146
|
+
|
124
147
|
get '/' do
|
125
148
|
erb :index
|
126
149
|
end
|
@@ -131,6 +154,9 @@ Renders <tt>./views/index.erb</tt>
|
|
131
154
|
|
132
155
|
The builder gem/library is required to render builder templates:
|
133
156
|
|
157
|
+
## You'll need to require builder in your app
|
158
|
+
require 'builder'
|
159
|
+
|
134
160
|
get '/' do
|
135
161
|
content_type 'application/xml', :charset => 'utf-8'
|
136
162
|
builder :index
|
@@ -142,6 +168,9 @@ Renders <tt>./views/index.builder</tt>.
|
|
142
168
|
|
143
169
|
The sass gem/library is required to render Sass templates:
|
144
170
|
|
171
|
+
## You'll need to require haml or sass in your app
|
172
|
+
require 'sass'
|
173
|
+
|
145
174
|
get '/stylesheet.css' do
|
146
175
|
content_type 'text/css', :charset => 'utf-8'
|
147
176
|
sass :stylesheet
|
@@ -149,6 +178,19 @@ The sass gem/library is required to render Sass templates:
|
|
149
178
|
|
150
179
|
Renders <tt>./views/stylesheet.sass</tt>.
|
151
180
|
|
181
|
+
{Sass' options}[http://haml.hamptoncatlin.com/docs/rdoc/classes/Sass.html]
|
182
|
+
can be set globally through Sinatra's configurations,
|
183
|
+
see {Options and Configurations}[http://www.sinatrarb.com/configuration.html],
|
184
|
+
and overridden on an individual basis.
|
185
|
+
|
186
|
+
set :sass, {:style => :compact } # default Sass style is :nested
|
187
|
+
|
188
|
+
get '/stylesheet.css' do
|
189
|
+
content_type 'text/css', :charset => 'utf-8'
|
190
|
+
sass :stylesheet, :sass_options => {:style => :expanded } # overridden
|
191
|
+
end
|
192
|
+
|
193
|
+
|
152
194
|
=== Inline Templates
|
153
195
|
|
154
196
|
get '/' do
|
data/Rakefile
CHANGED
@@ -2,7 +2,7 @@ require 'rake/clean'
|
|
2
2
|
require 'rake/testtask'
|
3
3
|
require 'fileutils'
|
4
4
|
|
5
|
-
task :default => [:test]
|
5
|
+
task :default => [:test, :compat]
|
6
6
|
task :spec => :test
|
7
7
|
|
8
8
|
# SPECS ===============================================================
|
@@ -12,8 +12,20 @@ Rake::TestTask.new(:test) do |t|
|
|
12
12
|
t.ruby_opts = ['-rubygems'] if defined? Gem
|
13
13
|
end
|
14
14
|
|
15
|
-
desc
|
16
|
-
task :compat do
|
15
|
+
desc "Run < 0.9.x compatibility specs"
|
16
|
+
task :compat do
|
17
|
+
begin
|
18
|
+
require 'mocha'
|
19
|
+
rescue LoadError
|
20
|
+
puts 'WARN: skipping compat tests. mocha gem required.'
|
21
|
+
next
|
22
|
+
end
|
23
|
+
|
24
|
+
if ! system('specrb --help &>/dev/null')
|
25
|
+
puts 'WARN: skipping compat tests. test-spec gem required.'
|
26
|
+
next
|
27
|
+
end
|
28
|
+
|
17
29
|
pattern = ENV['TEST'] || '.*'
|
18
30
|
sh "specrb --testcase '#{pattern}' -Ilib:test compat/*_test.rb"
|
19
31
|
end
|
data/compat/haml_test.rb
CHANGED
@@ -183,13 +183,14 @@ context "Haml" do
|
|
183
183
|
Sinatra.application = nil
|
184
184
|
end
|
185
185
|
|
186
|
-
specify '
|
186
|
+
specify 'default to filename and line of caller' do
|
187
187
|
|
188
188
|
get '/' do
|
189
189
|
haml 'foo'
|
190
190
|
end
|
191
191
|
|
192
|
-
Haml::Engine.expects(:new).with('foo', {
|
192
|
+
Haml::Engine.expects(:new).with('foo', {:filename => __FILE__,
|
193
|
+
:line => (__LINE__-4)}).returns(stub(:render => 'foo'))
|
193
194
|
|
194
195
|
get_it '/'
|
195
196
|
should.be.ok
|
@@ -202,7 +203,8 @@ context "Haml" do
|
|
202
203
|
haml 'foo', :options => {:format => :html4}
|
203
204
|
end
|
204
205
|
|
205
|
-
Haml::Engine.expects(:new).with('foo', {:
|
206
|
+
Haml::Engine.expects(:new).with('foo', {:filename => __FILE__,
|
207
|
+
:line => (__LINE__-4), :format => :html4}).returns(stub(:render => 'foo'))
|
206
208
|
|
207
209
|
get_it '/'
|
208
210
|
should.be.ok
|
@@ -220,7 +222,8 @@ context "Haml" do
|
|
220
222
|
haml 'foo'
|
221
223
|
end
|
222
224
|
|
223
|
-
Haml::Engine.expects(:new).with('foo', {:
|
225
|
+
Haml::Engine.expects(:new).with('foo', {:filename => __FILE__,
|
226
|
+
:line => (__LINE__-4), :format => :html4,
|
224
227
|
:escape_html => true}).returns(stub(:render => 'foo'))
|
225
228
|
|
226
229
|
get_it '/'
|
data/compat/helper.rb
CHANGED
data/compat/sass_test.rb
CHANGED
@@ -52,6 +52,16 @@ context "Sass" do
|
|
52
52
|
body.should.equal "#sass {\n background_color: #FFF; }\n"
|
53
53
|
end
|
54
54
|
|
55
|
+
it "passes :sass option to the Sass engine" do
|
56
|
+
get '/' do
|
57
|
+
sass "#sass\n :background-color #FFF\n :color #000\n", :sass => {:style => :compact}
|
58
|
+
end
|
59
|
+
|
60
|
+
get_it '/'
|
61
|
+
should.be.ok
|
62
|
+
body.should.equal "#sass { background-color: #FFF; color: #000; }\n"
|
63
|
+
end
|
64
|
+
|
55
65
|
end
|
56
66
|
|
57
67
|
end
|
data/lib/sinatra/base.rb
CHANGED
@@ -3,9 +3,10 @@ require 'time'
|
|
3
3
|
require 'uri'
|
4
4
|
require 'rack'
|
5
5
|
require 'rack/builder'
|
6
|
+
require 'sinatra/showexceptions'
|
6
7
|
|
7
8
|
module Sinatra
|
8
|
-
VERSION = '0.9.1.
|
9
|
+
VERSION = '0.9.1.3'
|
9
10
|
|
10
11
|
# The request object. See Rack::Request for more info:
|
11
12
|
# http://rack.rubyforge.org/doc/classes/Rack/Request.html
|
@@ -32,16 +33,6 @@ module Sinatra
|
|
32
33
|
# http://rack.rubyforge.org/doc/classes/Rack/Response.html
|
33
34
|
# http://rack.rubyforge.org/doc/classes/Rack/Response/Helpers.html
|
34
35
|
class Response < Rack::Response
|
35
|
-
def initialize
|
36
|
-
@status, @body = 200, []
|
37
|
-
@header = Rack::Utils::HeaderHash.new({'Content-Type' => 'text/html'})
|
38
|
-
end
|
39
|
-
|
40
|
-
def write(str)
|
41
|
-
@body << str.to_s
|
42
|
-
str
|
43
|
-
end
|
44
|
-
|
45
36
|
def finish
|
46
37
|
@body = block if block_given?
|
47
38
|
if [204, 304].include?(status.to_i)
|
@@ -231,103 +222,110 @@ module Sinatra
|
|
231
222
|
# :locals A hash with local variables that should be available
|
232
223
|
# in the template
|
233
224
|
module Templates
|
234
|
-
def erb(template, options={})
|
235
|
-
|
236
|
-
render :erb, template, options
|
225
|
+
def erb(template, options={}, locals={})
|
226
|
+
render :erb, template, options, locals
|
237
227
|
end
|
238
228
|
|
239
|
-
def haml(template, options={})
|
240
|
-
|
241
|
-
options[:options] ||= self.class.haml if self.class.respond_to? :haml
|
242
|
-
render :haml, template, options
|
229
|
+
def haml(template, options={}, locals={})
|
230
|
+
render :haml, template, options, locals
|
243
231
|
end
|
244
232
|
|
245
|
-
def sass(template, options={},
|
246
|
-
require 'sass' unless defined? ::Sass::Engine
|
233
|
+
def sass(template, options={}, locals={})
|
247
234
|
options[:layout] = false
|
248
|
-
render :sass, template, options
|
235
|
+
render :sass, template, options, locals
|
249
236
|
end
|
250
237
|
|
251
|
-
def builder(template=nil, options={}, &block)
|
252
|
-
require 'builder' unless defined? ::Builder
|
238
|
+
def builder(template=nil, options={}, locals={}, &block)
|
253
239
|
options, template = template, nil if template.is_a?(Hash)
|
254
240
|
template = lambda { block } if template.nil?
|
255
|
-
render :builder, template, options
|
241
|
+
render :builder, template, options, locals
|
256
242
|
end
|
257
243
|
|
258
244
|
private
|
259
|
-
def render(engine, template, options={})
|
260
|
-
|
261
|
-
|
262
|
-
|
245
|
+
def render(engine, template, options={}, locals={})
|
246
|
+
# merge app-level options
|
247
|
+
options = self.class.send(engine).merge(options) if self.class.respond_to?(engine)
|
248
|
+
|
249
|
+
# extract generic options
|
250
|
+
layout = options.delete(:layout)
|
251
|
+
layout = :layout if layout.nil? || layout == true
|
252
|
+
views = options.delete(:views) || self.class.views || "./views"
|
253
|
+
locals = options.delete(:locals) || locals || {}
|
254
|
+
|
255
|
+
# render template
|
256
|
+
data, options[:filename], options[:line] = lookup_template(engine, template, views)
|
257
|
+
output = __send__("render_#{engine}", template, data, options, locals)
|
258
|
+
|
259
|
+
# render layout
|
263
260
|
if layout
|
264
|
-
|
265
|
-
|
266
|
-
|
261
|
+
data, options[:filename], options[:line] = lookup_layout(engine, layout, views)
|
262
|
+
if data
|
263
|
+
output = __send__("render_#{engine}", layout, data, options, {}) { output }
|
264
|
+
end
|
267
265
|
end
|
266
|
+
|
267
|
+
output
|
268
268
|
end
|
269
269
|
|
270
|
-
def lookup_template(engine, template,
|
270
|
+
def lookup_template(engine, template, views_dir, filename = nil, line = nil)
|
271
271
|
case template
|
272
272
|
when Symbol
|
273
273
|
if cached = self.class.templates[template]
|
274
|
-
lookup_template(engine, cached,
|
274
|
+
lookup_template(engine, cached[:template], views_dir, cached[:filename], cached[:line])
|
275
275
|
else
|
276
|
-
::File.
|
276
|
+
path = ::File.join(views_dir, "#{template}.#{engine}")
|
277
|
+
[ ::File.read(path), path, 1 ]
|
277
278
|
end
|
278
279
|
when Proc
|
279
|
-
|
280
|
+
filename, line = self.class.caller_locations.first if filename.nil?
|
281
|
+
[ template.call, filename, line.to_i ]
|
280
282
|
when String
|
281
|
-
|
283
|
+
filename, line = self.class.caller_locations.first if filename.nil?
|
284
|
+
[ template, filename, line.to_i ]
|
282
285
|
else
|
283
286
|
raise ArgumentError
|
284
287
|
end
|
285
288
|
end
|
286
289
|
|
287
|
-
def lookup_layout(engine,
|
288
|
-
|
289
|
-
options.delete(:layout) if options[:layout] == true
|
290
|
-
template = options[:layout] || :layout
|
291
|
-
data = lookup_template(engine, template, options)
|
292
|
-
[template, data]
|
290
|
+
def lookup_layout(engine, template, views_dir)
|
291
|
+
lookup_template(engine, template, views_dir)
|
293
292
|
rescue Errno::ENOENT
|
294
293
|
nil
|
295
294
|
end
|
296
295
|
|
297
|
-
def
|
298
|
-
views_dir =
|
299
|
-
options[:views_directory] || self.options.views || "./views"
|
300
|
-
"#{views_dir}/#{template}.#{engine}"
|
301
|
-
end
|
302
|
-
|
303
|
-
def render_erb(template, data, options, &block)
|
296
|
+
def render_erb(template, data, options, locals, &block)
|
304
297
|
original_out_buf = @_out_buf
|
305
298
|
data = data.call if data.kind_of? Proc
|
306
299
|
|
307
300
|
instance = ::ERB.new(data, nil, nil, '@_out_buf')
|
308
|
-
locals = options[:locals] || {}
|
309
301
|
locals_assigns = locals.to_a.collect { |k,v| "#{k} = locals[:#{k}]" }
|
310
302
|
|
311
|
-
|
312
|
-
|
303
|
+
filename = options.delete(:filename) || '(__ERB__)'
|
304
|
+
line = options.delete(:line) || 1
|
305
|
+
line -= 1 if instance.src =~ /^#coding:/
|
306
|
+
|
307
|
+
render_binding = binding
|
308
|
+
eval locals_assigns.join("\n"), render_binding
|
309
|
+
eval instance.src, render_binding, filename, line
|
313
310
|
@_out_buf, result = original_out_buf, @_out_buf
|
314
311
|
result
|
315
312
|
end
|
316
313
|
|
317
|
-
def render_haml(template, data, options, &block)
|
318
|
-
|
319
|
-
engine.render(self, options[:locals] || {}, &block)
|
314
|
+
def render_haml(template, data, options, locals, &block)
|
315
|
+
::Haml::Engine.new(data, options).render(self, locals, &block)
|
320
316
|
end
|
321
317
|
|
322
|
-
def render_sass(template, data, options, &block)
|
323
|
-
|
324
|
-
engine.render
|
318
|
+
def render_sass(template, data, options, locals, &block)
|
319
|
+
::Sass::Engine.new(data, options).render
|
325
320
|
end
|
326
321
|
|
327
|
-
def render_builder(template, data, options, &block)
|
328
|
-
|
322
|
+
def render_builder(template, data, options, locals, &block)
|
323
|
+
options = { :indent => 2 }.merge(options)
|
324
|
+
filename = options.delete(:filename) || '<BUILDER>'
|
325
|
+
line = options.delete(:line) || 1
|
326
|
+
xml = ::Builder::XmlMarkup.new(options)
|
329
327
|
if data.respond_to?(:to_str)
|
330
|
-
eval data.to_str, binding,
|
328
|
+
eval data.to_str, binding, filename, line
|
331
329
|
elsif data.kind_of?(Proc)
|
332
330
|
data.call(xml)
|
333
331
|
end
|
@@ -409,7 +407,13 @@ module Sinatra
|
|
409
407
|
private
|
410
408
|
# Run before filters and then locate and run a matching route.
|
411
409
|
def route!
|
412
|
-
|
410
|
+
# enable nested params in Rack < 1.0; allow indifferent access
|
411
|
+
@params =
|
412
|
+
if Rack::Utils.respond_to?(:parse_nested_query)
|
413
|
+
indifferent_params(@request.params)
|
414
|
+
else
|
415
|
+
nested_params(@request.params)
|
416
|
+
end
|
413
417
|
|
414
418
|
# before filters
|
415
419
|
self.class.filters.each { |block| instance_eval(&block) }
|
@@ -443,24 +447,45 @@ module Sinatra
|
|
443
447
|
catch(:pass) do
|
444
448
|
conditions.each { |cond|
|
445
449
|
throw :pass if instance_eval(&cond) == false }
|
446
|
-
|
450
|
+
route_eval(&block)
|
447
451
|
end
|
448
452
|
end
|
449
453
|
end
|
450
454
|
end
|
451
455
|
|
452
|
-
|
453
|
-
|
456
|
+
route_missing
|
457
|
+
end
|
458
|
+
|
459
|
+
# Run a route block and throw :halt with the result.
|
460
|
+
def route_eval(&block)
|
461
|
+
throw :halt, instance_eval(&block)
|
462
|
+
end
|
463
|
+
|
464
|
+
# No matching route was found or all routes passed. The default
|
465
|
+
# implementation is to forward the request downstream when running
|
466
|
+
# as middleware (@app is non-nil); when no downstream app is set, raise
|
467
|
+
# a NotFound exception. Subclasses can override this method to perform
|
468
|
+
# custom route miss logic.
|
469
|
+
def route_missing
|
454
470
|
if @app
|
455
|
-
# Call bypassed method before forward to catch behavior that should
|
456
|
-
# happen even if no routes are hit.
|
457
|
-
bypassed if respond_to?(:bypassed)
|
458
471
|
forward
|
459
472
|
else
|
460
473
|
raise NotFound
|
461
474
|
end
|
462
475
|
end
|
463
476
|
|
477
|
+
# Enable string or symbol key access to the nested params hash.
|
478
|
+
def indifferent_params(params)
|
479
|
+
params = indifferent_hash.merge(params)
|
480
|
+
params.each do |key, value|
|
481
|
+
next unless value.is_a?(Hash)
|
482
|
+
params[key] = indifferent_params(value)
|
483
|
+
end
|
484
|
+
end
|
485
|
+
|
486
|
+
# Recursively replace the params hash with a nested indifferent
|
487
|
+
# hash. Rack 1.0 has a built in implementation of this method - remove
|
488
|
+
# this once Rack 1.0 is required.
|
464
489
|
def nested_params(params)
|
465
490
|
return indifferent_hash.merge(params) if !params.keys.join.include?('[')
|
466
491
|
params.inject indifferent_hash do |res, (key,val)|
|
@@ -532,7 +557,7 @@ module Sinatra
|
|
532
557
|
@env['sinatra.error'] = boom
|
533
558
|
|
534
559
|
dump_errors!(boom) if options.dump_errors?
|
535
|
-
raise boom if options.raise_errors?
|
560
|
+
raise boom if options.raise_errors? || options.show_exceptions?
|
536
561
|
|
537
562
|
@response.status = 500
|
538
563
|
error_block! boom.class, Exception
|
@@ -624,7 +649,8 @@ module Sinatra
|
|
624
649
|
|
625
650
|
# Define a named template. The block must return the template source.
|
626
651
|
def template(name, &block)
|
627
|
-
|
652
|
+
filename, line = caller_locations.first
|
653
|
+
templates[name] = { :filename => filename, :line => line, :template => block }
|
628
654
|
end
|
629
655
|
|
630
656
|
# Define the layout template. The block must return the template source.
|
@@ -636,12 +662,18 @@ module Sinatra
|
|
636
662
|
# when no file is specified.
|
637
663
|
def use_in_file_templates!(file=nil)
|
638
664
|
file ||= caller_files.first
|
639
|
-
|
665
|
+
app, data =
|
666
|
+
::IO.read(file).split(/^__END__$/, 2) rescue nil
|
667
|
+
|
668
|
+
if data
|
640
669
|
data.gsub!(/\r\n/, "\n")
|
670
|
+
lines = app.count("\n") + 1
|
641
671
|
template = nil
|
642
672
|
data.each_line do |line|
|
673
|
+
lines += 1
|
643
674
|
if line =~ /^@@\s*(.*)/
|
644
|
-
template =
|
675
|
+
template = ''
|
676
|
+
templates[$1.to_sym] = { :filename => file, :line => lines, :template => template }
|
645
677
|
elsif template
|
646
678
|
template << line
|
647
679
|
end
|
@@ -711,10 +743,10 @@ module Sinatra
|
|
711
743
|
route('HEAD', path, opts, &block)
|
712
744
|
end
|
713
745
|
|
714
|
-
def put(path, opts={}, &bk);
|
715
|
-
def post(path, opts={}, &bk);
|
716
|
-
def delete(path, opts={}, &bk); route 'DELETE', path, opts, &bk
|
717
|
-
def head(path, opts={}, &bk);
|
746
|
+
def put(path, opts={}, &bk); route 'PUT', path, opts, &bk end
|
747
|
+
def post(path, opts={}, &bk); route 'POST', path, opts, &bk end
|
748
|
+
def delete(path, opts={}, &bk); route 'DELETE', path, opts, &bk end
|
749
|
+
def head(path, opts={}, &bk); route 'HEAD', path, opts, &bk end
|
718
750
|
|
719
751
|
private
|
720
752
|
def route(verb, path, opts={}, &block)
|
@@ -734,7 +766,7 @@ module Sinatra
|
|
734
766
|
lambda { unbound_method.bind(self).call }
|
735
767
|
end
|
736
768
|
|
737
|
-
invoke_hook(:route_added, verb, path)
|
769
|
+
invoke_hook(:route_added, verb, path, block)
|
738
770
|
|
739
771
|
(routes[verb] ||= []).
|
740
772
|
push([pattern, keys, conditions, block]).last
|
@@ -790,14 +822,14 @@ module Sinatra
|
|
790
822
|
end
|
791
823
|
end
|
792
824
|
|
793
|
-
def development
|
794
|
-
def
|
795
|
-
def
|
825
|
+
def development?; environment == :development end
|
826
|
+
def production?; environment == :production end
|
827
|
+
def test?; environment == :test end
|
796
828
|
|
797
829
|
# Set configuration options for Sinatra and/or the app.
|
798
830
|
# Allows scoping of settings for certain environments.
|
799
831
|
def configure(*envs, &block)
|
800
|
-
yield if envs.empty? || envs.include?(environment.to_sym)
|
832
|
+
yield self if envs.empty? || envs.include?(environment.to_sym)
|
801
833
|
end
|
802
834
|
|
803
835
|
# Use the specified Rack middleware
|
@@ -836,8 +868,10 @@ module Sinatra
|
|
836
868
|
def new(*args, &bk)
|
837
869
|
builder = Rack::Builder.new
|
838
870
|
builder.use Rack::Session::Cookie if sessions? && !test?
|
839
|
-
builder.use Rack::CommonLogger
|
840
|
-
builder.use Rack::MethodOverride
|
871
|
+
builder.use Rack::CommonLogger if logging?
|
872
|
+
builder.use Rack::MethodOverride if methodoverride?
|
873
|
+
builder.use ShowExceptions if show_exceptions?
|
874
|
+
|
841
875
|
@middleware.each { |c,a,b| builder.use(c, *a, &b) }
|
842
876
|
builder.run super
|
843
877
|
builder.to_app
|
@@ -871,7 +905,7 @@ module Sinatra
|
|
871
905
|
servers = Array(self.server)
|
872
906
|
servers.each do |server_name|
|
873
907
|
begin
|
874
|
-
return Rack::Handler.get(server_name)
|
908
|
+
return Rack::Handler.get(server_name.capitalize)
|
875
909
|
rescue LoadError
|
876
910
|
rescue NameError
|
877
911
|
end
|
@@ -898,24 +932,32 @@ module Sinatra
|
|
898
932
|
send :define_method, message, &block
|
899
933
|
end
|
900
934
|
|
935
|
+
public
|
936
|
+
CALLERS_TO_IGNORE = [
|
937
|
+
/lib\/sinatra.*\.rb$/, # all sinatra code
|
938
|
+
/\(.*\)/, # generated code
|
939
|
+
/custom_require\.rb$/, # rubygems require hacks
|
940
|
+
/active_support/, # active_support require hacks
|
941
|
+
] unless self.const_defined?('CALLERS_TO_IGNORE')
|
942
|
+
|
901
943
|
# Like Kernel#caller but excluding certain magic entries and without
|
902
944
|
# line / method information; the resulting array contains filenames only.
|
903
945
|
def caller_files
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
]
|
946
|
+
caller_locations.
|
947
|
+
map { |file,line| file }
|
948
|
+
end
|
949
|
+
|
950
|
+
def caller_locations
|
910
951
|
caller(1).
|
911
|
-
map { |line| line.split(
|
912
|
-
reject { |file|
|
952
|
+
map { |line| line.split(/:(?=\d|in )/)[0,2] }.
|
953
|
+
reject { |file,line| CALLERS_TO_IGNORE.any? { |pattern| file =~ pattern } }
|
913
954
|
end
|
914
955
|
end
|
915
956
|
|
916
957
|
set :raise_errors, true
|
917
958
|
set :dump_errors, false
|
918
959
|
set :clean_trace, true
|
960
|
+
set :show_exceptions, Proc.new { development? }
|
919
961
|
set :sessions, false
|
920
962
|
set :logging, false
|
921
963
|
set :methodoverride, false
|
@@ -957,6 +999,8 @@ module Sinatra
|
|
957
999
|
end
|
958
1000
|
|
959
1001
|
error NotFound do
|
1002
|
+
content_type 'text/html'
|
1003
|
+
|
960
1004
|
(<<-HTML).gsub(/^ {8}/, '')
|
961
1005
|
<!DOCTYPE html>
|
962
1006
|
<html>
|
@@ -978,35 +1022,6 @@ module Sinatra
|
|
978
1022
|
</html>
|
979
1023
|
HTML
|
980
1024
|
end
|
981
|
-
|
982
|
-
error do
|
983
|
-
next unless err = request.env['sinatra.error']
|
984
|
-
heading = err.class.name + ' - ' + err.message.to_s
|
985
|
-
(<<-HTML).gsub(/^ {8}/, '')
|
986
|
-
<!DOCTYPE html>
|
987
|
-
<html>
|
988
|
-
<head>
|
989
|
-
<style type="text/css">
|
990
|
-
body {font-family:verdana;color:#333}
|
991
|
-
#c {margin-left:20px}
|
992
|
-
h1 {color:#1D6B8D;margin:0;margin-top:-30px}
|
993
|
-
h2 {color:#1D6B8D;font-size:18px}
|
994
|
-
pre {border-left:2px solid #ddd;padding-left:10px;color:#000}
|
995
|
-
img {margin-top:10px}
|
996
|
-
</style>
|
997
|
-
</head>
|
998
|
-
<body>
|
999
|
-
<div id="c">
|
1000
|
-
<img src="/__sinatra__/500.png">
|
1001
|
-
<h1>#{escape_html(heading)}</h1>
|
1002
|
-
<pre>#{escape_html(clean_backtrace(err.backtrace) * "\n")}</pre>
|
1003
|
-
<h2>Params</h2>
|
1004
|
-
<pre>#{escape_html(params.inspect)}</pre>
|
1005
|
-
</div>
|
1006
|
-
</body>
|
1007
|
-
</html>
|
1008
|
-
HTML
|
1009
|
-
end
|
1010
1025
|
end
|
1011
1026
|
end
|
1012
1027
|
|