sinatra-sinatra 0.9.1.2 → 0.9.1.3
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/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
|
|