diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000..7f839567
--- /dev/null
+++ b/.travis.yml
@@ -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
diff --git a/Gemfile b/Gemfile
index 878cd26b..5a61cfd7 100644
--- a/Gemfile
+++ b/Gemfile
@@ -38,7 +38,11 @@ gem 'kramdown'
gem 'maruku'
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"
# C extensions
diff --git a/README.es.rdoc b/README.es.rdoc
index 0825d948..11129a35 100644
--- a/README.es.rdoc
+++ b/README.es.rdoc
@@ -100,6 +100,13 @@ O con un parámetro de bloque:
"Hola, #{c}!"
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
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 :layout_engine.
Dependencias:: {rdoc}[http://rdoc.rubyforge.org/]
Extensiones de Archivo:: .rdoc
-Ejemplo:: textile :LEEME, :layout_engine => :erb
+Ejemplo:: rdoc :LEEME, :layout_engine => :erb
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:
@@ -1850,3 +1857,4 @@ siguiendo las especificaciones SemVer y SemVerTag.
{última versión liberada}[http://rubydoc.info/gems/sinatra] o para la
{rama de desarrollo actual}[http://rubydoc.info/github/sinatra/sinatra]
en http://rubydoc.info/
+* {Servidor de IC}[http://ci.rkh.im/view/Sinatra/]
diff --git a/README.rdoc b/README.rdoc
index 50448f18..0bf9f310 100644
--- a/README.rdoc
+++ b/README.rdoc
@@ -98,6 +98,12 @@ Or with a block parameter:
"Hello, #{c}!"
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
Routes may include a variety of matching conditions, such as the user agent:
diff --git a/lib/sinatra/base.rb b/lib/sinatra/base.rb
index 5c6b3360..99cc0802 100644
--- a/lib/sinatra/base.rb
+++ b/lib/sinatra/base.rb
@@ -700,12 +700,12 @@ module Sinatra
# Revert params afterwards.
#
# 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
route = @request.path_info
route = '/' if route.empty? and not settings.empty_path_info?
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 =
if keys.any?
keys.zip(values).inject({}) do |hash,(k,v)|
@@ -801,29 +801,33 @@ module Sinatra
def handle_exception!(boom)
@env['sinatra.error'] = boom
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?
headers['X-Cascade'] = 'pass'
body '
Not Found
'
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?
raise boom if settings.raise_errors? or settings.show_exceptions?
- error_block! Exception
+ error_block! Exception, boom
end
# Find an custom error block for the key(s) specified.
- def error_block!(key)
+ def error_block!(key, *block_params)
base = settings
while base.respond_to?(:errors)
next base = base.superclass unless args = base.errors[key]
+ args += [block_params]
return process_route(*args)
end
return false unless key.respond_to? :superclass and key.superclass < Exception
- error_block! key.superclass
+ error_block!(key.superclass, *block_params)
end
def dump_errors!(boom)
diff --git a/lib/sinatra/showexceptions.rb b/lib/sinatra/showexceptions.rb
index 73558c04..993537b2 100644
--- a/lib/sinatra/showexceptions.rb
+++ b/lib/sinatra/showexceptions.rb
@@ -252,7 +252,7 @@ TEMPLATE = <<-HTML # :nodoc:
GET
- <% unless req.GET.empty? %>
+ <% if req.GET and not req.GET.empty? %>
Variable |
@@ -273,7 +273,7 @@ TEMPLATE = <<-HTML # :nodoc:
POST
- <% unless req.POST.empty? %>
+ <% if req.POST and not req.POST.empty? %>
Variable |
diff --git a/sinatra.gemspec b/sinatra.gemspec
index 178b6c7c..e6c0a781 100644
--- a/sinatra.gemspec
+++ b/sinatra.gemspec
@@ -2,8 +2,8 @@ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
require 'sinatra/version'
Gem::Specification.new 'sinatra', Sinatra::VERSION do |s|
- s.description = "Classy web-development dressed in a DSL"
- s.summary = s.description
+ s.description = "Sinatra is a DSL for quickly creating web applications in Ruby with minimal effort."
+ s.summary = "Classy web-development dressed in a DSL"
s.authors = ["Blake Mizerany", "Ryan Tomayko", "Simon Rozet", "Konstantin Haase"]
s.email = "sinatrarb@googlegroups.com"
s.homepage = "http://www.sinatrarb.com/"
diff --git a/test/mapped_error_test.rb b/test/mapped_error_test.rb
index d1b98104..0a16af73 100644
--- a/test/mapped_error_test.rb
+++ b/test/mapped_error_test.rb
@@ -29,6 +29,15 @@ class MappedErrorTest < Test::Unit::TestCase
assert_equal 'Foo!', body
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
mock_app {
set :raise_errors, false
@@ -112,12 +121,7 @@ class MappedErrorTest < Test::Unit::TestCase
end
it "never raises Sinatra::NotFound beyond the application" do
- mock_app {
- set :raise_errors, true
- get '/' do
- raise Sinatra::NotFound
- end
- }
+ mock_app(Sinatra::Application) { get('/') { raise Sinatra::NotFound }}
assert_nothing_raised { get '/' }
assert_equal 404, status
end
diff --git a/test/slim_test.rb b/test/slim_test.rb
index 12b60368..b860bffb 100644
--- a/test/slim_test.rb
+++ b/test/slim_test.rb
@@ -54,7 +54,7 @@ class SlimTest < Test::Unit::TestCase
it "passes slim options to the slim engine" do
mock_app {
get '/' do
- slim "! doctype html\nh1 Hello World", :format => :html4
+ slim "doctype html\nh1 Hello World", :format => :html4
end
}
get '/'
@@ -66,7 +66,7 @@ class SlimTest < Test::Unit::TestCase
mock_app {
set :slim, {:format => :html4}
get '/' do
- slim "! doctype html\nh1 Hello World"
+ slim "doctype html\nh1 Hello World"
end
}
get '/'
@@ -78,10 +78,10 @@ class SlimTest < Test::Unit::TestCase
mock_app {
set :slim, {:format => :html4}
get '/' do
- slim "! doctype html\nh1.header Hello World"
+ slim "doctype html\nh1.header Hello World"
end
get '/html5' do
- slim "! doctype html\nh1.header Hello World", :format => :html5
+ slim "doctype html\nh1.header Hello World", :format => :html5
end
}
get '/'