sinatra 0.9.0.3 → 0.9.0.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sinatra might be problematic. Click here for more details.

data/CHANGES CHANGED
@@ -1,3 +1,12 @@
1
+ = 0.9.0.4 / 2009-01-25
2
+
3
+ * Using halt with more than 1 args causes ArgumentError [#131]
4
+ * using halt in a before filter doesn't modify response [#127]
5
+ * Add deprecated Sinatra::EventContext to unbreak plugins [#130]
6
+ * Give access to GET/POST params in filters [#129]
7
+ * Preserve non-nested params in nested params hash [#117]
8
+ * Fix backtrace dump with Rack::Lint [#116]
9
+
1
10
  = 0.9.0.3 / 2009-01-21
2
11
 
3
12
  * Fall back on mongrel then webrick when thin not found. [#75]
@@ -0,0 +1,12 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ context "Compat" do
4
+ setup do
5
+ Sinatra.application = nil
6
+ @app = Sinatra.application
7
+ end
8
+
9
+ specify "makes EventContext available" do
10
+ assert_same Sinatra::Default, Sinatra::EventContext
11
+ end
12
+ end
@@ -4,7 +4,7 @@ require 'rack'
4
4
  require 'rack/builder'
5
5
 
6
6
  module Sinatra
7
- VERSION = '0.9.0.3'
7
+ VERSION = '0.9.0.4'
8
8
 
9
9
  class Request < Rack::Request
10
10
  def user_agent
@@ -311,7 +311,11 @@ module Sinatra
311
311
  @request = Request.new(env)
312
312
  @response = Response.new
313
313
  @params = nil
314
- error_detection { dispatch! }
314
+
315
+ invoke { dispatch! }
316
+ invoke { error_block!(response.status) }
317
+
318
+ @response.body = [] if @env['REQUEST_METHOD'] == 'HEAD'
315
319
  @response.finish
316
320
  end
317
321
 
@@ -320,7 +324,8 @@ module Sinatra
320
324
  end
321
325
 
322
326
  def halt(*response)
323
- throw :halt, *response
327
+ response = response.first if response.length == 1
328
+ throw :halt, response
324
329
  end
325
330
 
326
331
  def pass
@@ -328,19 +333,21 @@ module Sinatra
328
333
  end
329
334
 
330
335
  private
331
- def dispatch!
332
- self.class.filters.each do |block|
333
- res = catch(:halt) { instance_eval(&block) ; :continue }
334
- return unless res == :continue
335
- end
336
+ # Run before filters and then locate and run a matching route.
337
+ def route!
338
+ @params = nested_params(@request.params)
336
339
 
340
+ # before filters
341
+ self.class.filters.each { |block| instance_eval(&block) }
342
+
343
+ # routes
337
344
  if routes = self.class.routes[@request.request_method]
345
+ original_params = @params
338
346
  path = @request.path_info
339
- original_params = nested_params(@request.params)
340
347
 
341
- routes.each do |pattern, keys, conditions, method_name|
342
- if pattern =~ path
343
- values = $~.captures.map{|val| val && unescape(val) }
348
+ routes.each do |pattern, keys, conditions, block|
349
+ if match = pattern.match(path)
350
+ values = match.captures.map{|val| val && unescape(val) }
344
351
  params =
345
352
  if keys.any?
346
353
  keys.zip(values).inject({}) do |hash,(k,v)|
@@ -358,14 +365,15 @@ module Sinatra
358
365
  end
359
366
  @params = original_params.merge(params)
360
367
 
361
- catch(:pass) {
368
+ catch(:pass) do
362
369
  conditions.each { |cond|
363
370
  throw :pass if instance_eval(&cond) == false }
364
- return invoke(method_name)
365
- }
371
+ throw :halt, instance_eval(&block)
372
+ end
366
373
  end
367
374
  end
368
375
  end
376
+
369
377
  raise NotFound
370
378
  end
371
379
 
@@ -376,6 +384,8 @@ module Sinatra
376
384
  splat = key.scan(/(^[^\[]+)|\[([^\]]+)\]/).flatten.compact
377
385
  head, last = splat[0..-2], splat[-1]
378
386
  head.inject(res){ |s,v| s[v] ||= indifferent_hash }[last] = val
387
+ else
388
+ res[key] = val
379
389
  end
380
390
  res
381
391
  end
@@ -385,7 +395,8 @@ module Sinatra
385
395
  Hash.new {|hash,key| hash[key.to_s] if Symbol === key }
386
396
  end
387
397
 
388
- def invoke(block)
398
+ # Run the block with 'throw :halt' support and apply result to the response.
399
+ def invoke(&block)
389
400
  res = catch(:halt) { instance_eval(&block) }
390
401
  return if res.nil?
391
402
 
@@ -417,30 +428,38 @@ module Sinatra
417
428
  res
418
429
  end
419
430
 
420
- def error_detection
421
- errmap = self.class.errors
422
- yield
431
+ # Dispatch a request with error handling.
432
+ def dispatch!
433
+ route!
423
434
  rescue NotFound => boom
424
435
  @env['sinatra.error'] = boom
425
436
  @response.status = 404
426
437
  @response.body = ['<h1>Not Found</h1>']
427
- handler = errmap[boom.class] || errmap[NotFound]
428
- invoke handler unless handler.nil?
438
+ error_block! boom.class, NotFound
439
+
429
440
  rescue ::Exception => boom
430
441
  @env['sinatra.error'] = boom
431
442
 
432
443
  if options.dump_errors?
433
444
  msg = ["#{boom.class} - #{boom.message}:", *boom.backtrace].join("\n ")
434
- @env['rack.errors'] << msg
445
+ @env['rack.errors'].write msg
435
446
  end
436
447
 
437
448
  raise boom if options.raise_errors?
438
449
  @response.status = 500
439
- invoke errmap[boom.class] || errmap[Exception]
440
- ensure
441
- if @response.status >= 400 && errmap.key?(response.status)
442
- invoke errmap[response.status]
450
+ error_block! boom.class, Exception
451
+ end
452
+
453
+ # Find an custom error block for the key(s) specified.
454
+ def error_block!(*keys)
455
+ errmap = self.class.errors
456
+ keys.each do |key|
457
+ if block = errmap[key]
458
+ res = instance_eval(&block)
459
+ return res
460
+ end
443
461
  end
462
+ nil
444
463
  end
445
464
 
446
465
  @routes = {}
@@ -570,7 +589,7 @@ module Sinatra
570
589
  route('GET', path, opts, &block)
571
590
 
572
591
  @conditions = conditions
573
- head(path, opts) { invoke(block) ; [] }
592
+ route('HEAD', path, opts, &block)
574
593
  end
575
594
 
576
595
  def put(path, opts={}, &bk); route 'PUT', path, opts, &bk; end
@@ -51,6 +51,17 @@ module Sinatra
51
51
  module Compat
52
52
  end
53
53
 
54
+ # Make Sinatra::EventContext an alias for Sinatra::Default to unbreak plugins.
55
+ def self.const_missing(const_name)
56
+ if const_name == :EventContext
57
+ const_set :EventContext, Sinatra::Default
58
+ sinatra_warn 'Sinatra::EventContext is deprecated; use Sinatra::Default instead.'
59
+ Sinatra::Default
60
+ else
61
+ super
62
+ end
63
+ end
64
+
54
65
  # The ServerError exception is deprecated. Any exception is considered an
55
66
  # internal server error.
56
67
  class ServerError < RuntimeError
@@ -107,7 +118,7 @@ module Sinatra
107
118
  # Throwing halt with a Symbol and the to_result convention are
108
119
  # deprecated. Override the invoke method to detect those types of return
109
120
  # values.
110
- def invoke(handler)
121
+ def invoke(&block)
111
122
  res = super
112
123
  case
113
124
  when res.kind_of?(Symbol)
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
3
3
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
4
4
 
5
5
  s.name = 'sinatra'
6
- s.version = '0.9.0.3'
7
- s.date = '2009-01-21'
6
+ s.version = '0.9.0.4'
7
+ s.date = '2009-01-25'
8
8
 
9
9
  s.description = "Classy web-development dressed in a DSL"
10
10
  s.summary = "Classy web-development dressed in a DSL"
@@ -22,6 +22,7 @@ Gem::Specification.new do |s|
22
22
  compat/app_test.rb
23
23
  compat/application_test.rb
24
24
  compat/builder_test.rb
25
+ compat/compat_test.rb
25
26
  compat/custom_error_test.rb
26
27
  compat/erb_test.rb
27
28
  compat/events_test.rb
@@ -72,4 +72,28 @@ describe "Filters" do
72
72
  assert ok?
73
73
  assert_equal 'cool', body
74
74
  end
75
+
76
+ it "does modify the response with halt" do
77
+ mock_app {
78
+ before { halt 302, 'Hi' }
79
+ get '/foo' do
80
+ "should not happen"
81
+ end
82
+ }
83
+
84
+ get '/foo'
85
+ assert_equal 302, response.status
86
+ assert_equal 'Hi', body
87
+ end
88
+
89
+ it "gives you access to params" do
90
+ mock_app {
91
+ before { @foo = params['foo'] }
92
+ get('/foo') { @foo }
93
+ }
94
+
95
+ get '/foo?foo=cool'
96
+ assert ok?
97
+ assert_equal 'cool', body
98
+ end
75
99
  end
@@ -1,7 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/helper'
2
2
 
3
3
  describe "Routing" do
4
- %w[get put post delete head].each do |verb|
4
+ %w[get put post delete].each do |verb|
5
5
  it "defines #{verb.upcase} request handlers with #{verb}" do
6
6
  mock_app {
7
7
  send verb, '/hello' do
@@ -16,6 +16,21 @@ describe "Routing" do
16
16
  end
17
17
  end
18
18
 
19
+ it "defines HEAD request handlers with HEAD" do
20
+ mock_app {
21
+ head '/hello' do
22
+ response['X-Hello'] = 'World!'
23
+ 'remove me'
24
+ end
25
+ }
26
+
27
+ request = Rack::MockRequest.new(@app)
28
+ response = request.request('HEAD', '/hello', {})
29
+ assert response.ok?
30
+ assert_equal 'World!', response['X-Hello']
31
+ assert_equal '', response.body
32
+ end
33
+
19
34
  it "404s when no route satisfies the request" do
20
35
  mock_app {
21
36
  get('/foo') { }
@@ -176,6 +191,21 @@ describe "Routing" do
176
191
  assert_equal 'looks good', body
177
192
  end
178
193
 
194
+ it "preserves non-nested params" do
195
+ mock_app {
196
+ get '/foo' do
197
+ assert_equal "2", params["article_id"]
198
+ assert_equal "awesome", params['comment']['body']
199
+ assert_nil params['comment[body]']
200
+ 'looks good'
201
+ end
202
+ }
203
+
204
+ get '/foo?article_id=2&comment[body]=awesome'
205
+ assert ok?
206
+ assert_equal 'looks good', body
207
+ end
208
+
179
209
  it "supports paths that include spaces" do
180
210
  mock_app {
181
211
  get '/path with spaces' do
@@ -239,6 +269,30 @@ describe "Routing" do
239
269
  assert_equal 'Hello World', body
240
270
  end
241
271
 
272
+ it "halts with a response tuple" do
273
+ mock_app {
274
+ get '/' do
275
+ halt 295, {'Content-Type' => 'text/plain'}, 'Hello World'
276
+ end
277
+ }
278
+
279
+ get '/'
280
+ assert_equal 295, status
281
+ assert_equal 'text/plain', response['Content-Type']
282
+ assert_equal 'Hello World', body
283
+ end
284
+
285
+ it "halts with an array of strings" do
286
+ mock_app {
287
+ get '/' do
288
+ halt %w[Hello World How Are You]
289
+ end
290
+ }
291
+
292
+ get '/'
293
+ assert_equal 'HelloWorldHowAreYou', body
294
+ end
295
+
242
296
  it "transitions to the next matching route on pass" do
243
297
  mock_app {
244
298
  get '/:foo' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sinatra
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0.3
4
+ version: 0.9.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Blake Mizerany
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-01-21 00:00:00 -08:00
12
+ date: 2009-01-25 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -40,6 +40,7 @@ files:
40
40
  - compat/app_test.rb
41
41
  - compat/application_test.rb
42
42
  - compat/builder_test.rb
43
+ - compat/compat_test.rb
43
44
  - compat/custom_error_test.rb
44
45
  - compat/erb_test.rb
45
46
  - compat/events_test.rb