1
0
Fork 0
mirror of https://github.com/sinatra/sinatra synced 2023-03-27 23:18:01 -04:00

Merge remote-tracking branch 'upstream/master'

This commit is contained in:
michelc 2011-08-02 18:04:14 +02:00
commit ba01aa8694
9 changed files with 66 additions and 24 deletions

16
.travis.yml Normal file
View file

@ -0,0 +1,16 @@
rvm:
- 1.8.7
- 1.9.2
- 1.9.3
- rbx
- rbx-2.0
# - jruby
- ruby-head
env:
- "rack=1.3.0"
- "rack=master"
- "tilt=1.3.2"
- "tilt=master"
notifications:
recipients:
- k.haase@finn.de

View file

@ -38,7 +38,11 @@ gem 'kramdown'
gem 'maruku' gem 'maruku'
gem 'creole' gem 'creole'
gem 'nokogiri' if RUBY_ENGINE != 'maglev' if RUBY_ENGINE == 'jruby'
gem 'nokogiri', '!= 1.5.0'
elsif RUBY_ENGINE != 'maglev'
gem 'nokogiri'
end
unless RUBY_ENGINE == 'jruby' && JRUBY_VERSION < "1.6.1" unless RUBY_ENGINE == 'jruby' && JRUBY_VERSION < "1.6.1"
# C extensions # C extensions

View file

@ -100,6 +100,13 @@ O con un parámetro de bloque:
"Hola, #{c}!" "Hola, #{c}!"
end end
Los patrones de ruta pueden contener parámetros opcionales:
get '/posts.?:formato?' do
# coincide con "GET /posts" y además admite cualquier extensión, por
# ejemplo, "GET /posts.json", "GET /posts.xml", etc.
end
=== Condiciones === Condiciones
Las rutas pueden incluir una variedad de condiciones de selección, como por Las rutas pueden incluir una variedad de condiciones de selección, como por
@ -431,7 +438,7 @@ layout distinto al de la plantilla pasando la opción <tt>:layout_engine</tt>.
Dependencias:: {rdoc}[http://rdoc.rubyforge.org/] Dependencias:: {rdoc}[http://rdoc.rubyforge.org/]
Extensiones de Archivo:: <tt>.rdoc</tt> Extensiones de Archivo:: <tt>.rdoc</tt>
Ejemplo:: <tt>textile :LEEME, :layout_engine => :erb</tt> Ejemplo:: <tt>rdoc :LEEME, :layout_engine => :erb</tt>
No es posible llamar métodos desde rdoc, ni pasarle locales. Por lo tanto, No es posible llamar métodos desde rdoc, ni pasarle locales. Por lo tanto,
generalmente vas a usarlo en combinación con otro motor de renderizado: generalmente vas a usarlo en combinación con otro motor de renderizado:
@ -1850,3 +1857,4 @@ siguiendo las especificaciones SemVer y SemVerTag.
{última versión liberada}[http://rubydoc.info/gems/sinatra] o para la {última versión liberada}[http://rubydoc.info/gems/sinatra] o para la
{rama de desarrollo actual}[http://rubydoc.info/github/sinatra/sinatra] {rama de desarrollo actual}[http://rubydoc.info/github/sinatra/sinatra]
en http://rubydoc.info/ en http://rubydoc.info/
* {Servidor de IC}[http://ci.rkh.im/view/Sinatra/]

View file

@ -98,6 +98,12 @@ Or with a block parameter:
"Hello, #{c}!" "Hello, #{c}!"
end end
Route patterns may have optional parameters:
get '/posts.?:format?' do
# matches "GET /posts" and any extension "GET /posts.json", "GET /posts.xml" etc.
end
=== Conditions === Conditions
Routes may include a variety of matching conditions, such as the user agent: Routes may include a variety of matching conditions, such as the user agent:

View file

@ -700,12 +700,12 @@ module Sinatra
# Revert params afterwards. # Revert params afterwards.
# #
# Returns pass block. # Returns pass block.
def process_route(pattern, keys, conditions, block = nil, values = nil) def process_route(pattern, keys, conditions, block = nil, values = [])
@original_params ||= @params @original_params ||= @params
route = @request.path_info route = @request.path_info
route = '/' if route.empty? and not settings.empty_path_info? route = '/' if route.empty? and not settings.empty_path_info?
if match = pattern.match(route) if match = pattern.match(route)
values = match.captures.to_a.map { |v| force_encoding URI.decode(v) if v } values += match.captures.to_a.map { |v| force_encoding URI.decode(v) if v }
params = params =
if keys.any? if keys.any?
keys.zip(values).inject({}) do |hash,(k,v)| keys.zip(values).inject({}) do |hash,(k,v)|
@ -801,29 +801,33 @@ module Sinatra
def handle_exception!(boom) def handle_exception!(boom)
@env['sinatra.error'] = boom @env['sinatra.error'] = boom
status boom.respond_to?(:code) ? Integer(boom.code) : 500 status boom.respond_to?(:code) ? Integer(boom.code) : 500
dump_errors! boom if settings.dump_errors? and server_error?
raise boom if settings.show_exceptions? and settings.show_exceptions != :after_handler if server_error?
dump_errors! boom if settings.dump_errors?
raise boom if settings.show_exceptions? and settings.show_exceptions != :after_handler
end
if not_found? if not_found?
headers['X-Cascade'] = 'pass' headers['X-Cascade'] = 'pass'
body '<h1>Not Found</h1>' body '<h1>Not Found</h1>'
end end
res = error_block!(boom.class) || error_block!(status) res = error_block!(boom.class, boom) || error_block!(status, boom)
return res if res or not server_error? return res if res or not server_error?
raise boom if settings.raise_errors? or settings.show_exceptions? raise boom if settings.raise_errors? or settings.show_exceptions?
error_block! Exception error_block! Exception, boom
end end
# Find an custom error block for the key(s) specified. # Find an custom error block for the key(s) specified.
def error_block!(key) def error_block!(key, *block_params)
base = settings base = settings
while base.respond_to?(:errors) while base.respond_to?(:errors)
next base = base.superclass unless args = base.errors[key] next base = base.superclass unless args = base.errors[key]
args += [block_params]
return process_route(*args) return process_route(*args)
end end
return false unless key.respond_to? :superclass and key.superclass < Exception return false unless key.respond_to? :superclass and key.superclass < Exception
error_block! key.superclass error_block!(key.superclass, *block_params)
end end
def dump_errors!(boom) def dump_errors!(boom)

View file

@ -252,7 +252,7 @@ TEMPLATE = <<-HTML # :nodoc:
<div id="get"> <div id="get">
<h3 id="get-info">GET</h3> <h3 id="get-info">GET</h3>
<% unless req.GET.empty? %> <% if req.GET and not req.GET.empty? %>
<table class="req"> <table class="req">
<tr> <tr>
<th>Variable</th> <th>Variable</th>
@ -273,7 +273,7 @@ TEMPLATE = <<-HTML # :nodoc:
<div id="post"> <div id="post">
<h3 id="post-info">POST</h3> <h3 id="post-info">POST</h3>
<% unless req.POST.empty? %> <% if req.POST and not req.POST.empty? %>
<table class="req"> <table class="req">
<tr> <tr>
<th>Variable</th> <th>Variable</th>

View file

@ -2,8 +2,8 @@ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
require 'sinatra/version' require 'sinatra/version'
Gem::Specification.new 'sinatra', Sinatra::VERSION do |s| Gem::Specification.new 'sinatra', Sinatra::VERSION do |s|
s.description = "Classy web-development dressed in a DSL" s.description = "Sinatra is a DSL for quickly creating web applications in Ruby with minimal effort."
s.summary = s.description s.summary = "Classy web-development dressed in a DSL"
s.authors = ["Blake Mizerany", "Ryan Tomayko", "Simon Rozet", "Konstantin Haase"] s.authors = ["Blake Mizerany", "Ryan Tomayko", "Simon Rozet", "Konstantin Haase"]
s.email = "sinatrarb@googlegroups.com" s.email = "sinatrarb@googlegroups.com"
s.homepage = "http://www.sinatrarb.com/" s.homepage = "http://www.sinatrarb.com/"

View file

@ -29,6 +29,15 @@ class MappedErrorTest < Test::Unit::TestCase
assert_equal 'Foo!', body assert_equal 'Foo!', body
end end
it 'passes the exception object to the error handler' do
mock_app do
set :raise_errors, false
error(FooError) { |e| assert_equal(FooError, e.class) }
get('/') { raise FooError }
end
get('/')
end
it 'uses the Exception handler if no matching handler found' do it 'uses the Exception handler if no matching handler found' do
mock_app { mock_app {
set :raise_errors, false set :raise_errors, false
@ -112,12 +121,7 @@ class MappedErrorTest < Test::Unit::TestCase
end end
it "never raises Sinatra::NotFound beyond the application" do it "never raises Sinatra::NotFound beyond the application" do
mock_app { mock_app(Sinatra::Application) { get('/') { raise Sinatra::NotFound }}
set :raise_errors, true
get '/' do
raise Sinatra::NotFound
end
}
assert_nothing_raised { get '/' } assert_nothing_raised { get '/' }
assert_equal 404, status assert_equal 404, status
end end

View file

@ -54,7 +54,7 @@ class SlimTest < Test::Unit::TestCase
it "passes slim options to the slim engine" do it "passes slim options to the slim engine" do
mock_app { mock_app {
get '/' do get '/' do
slim "! doctype html\nh1 Hello World", :format => :html4 slim "doctype html\nh1 Hello World", :format => :html4
end end
} }
get '/' get '/'
@ -66,7 +66,7 @@ class SlimTest < Test::Unit::TestCase
mock_app { mock_app {
set :slim, {:format => :html4} set :slim, {:format => :html4}
get '/' do get '/' do
slim "! doctype html\nh1 Hello World" slim "doctype html\nh1 Hello World"
end end
} }
get '/' get '/'
@ -78,10 +78,10 @@ class SlimTest < Test::Unit::TestCase
mock_app { mock_app {
set :slim, {:format => :html4} set :slim, {:format => :html4}
get '/' do get '/' do
slim "! doctype html\nh1.header Hello World" slim "doctype html\nh1.header Hello World"
end end
get '/html5' do get '/html5' do
slim "! doctype html\nh1.header Hello World", :format => :html5 slim "doctype html\nh1.header Hello World", :format => :html5
end end
} }
get '/' get '/'