From 8281ff9caed1241528f1c435da5a75ee1db5f321 Mon Sep 17 00:00:00 2001 From: Blake Mizerany Date: Wed, 21 Nov 2007 02:50:42 -0800 Subject: [PATCH] custom 404's and 500's --- lib/sinatra.rb | 36 ++++++++++++++++++++++++++++++++++-- test/dispatching_test.rb | 38 +++++++++++++++++++++++++++++++++++++- test/helper.rb | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+), 3 deletions(-) diff --git a/lib/sinatra.rb b/lib/sinatra.rb index d14fa7b..f5bab38 100644 --- a/lib/sinatra.rb +++ b/lib/sinatra.rb @@ -11,6 +11,20 @@ class String end end +class Hash + def to_params + map { |k,v| "#{k}=#{URI.escape(v)}" }.join('&') + end + + def symbolize_keys + self.inject({}) { |h,(k,v)| h[k.to_sym] = v; h } + end + + def pass(*keys) + reject { |k,v| !keys.include?(k) } + end +end + class Symbol def to_proc Proc.new { |*args| args.shift.__send__(self, *args) } @@ -38,6 +52,10 @@ end module Sinatra extend self + Error = Proc.new do + "#{$!.message}\n\t#{$!.backtrace.join("\n\t")}" + end + def request_types @request_types ||= [:get, :put, :post, :delete] end @@ -48,8 +66,22 @@ module Sinatra end end - def determine_event(verb, path) - routes[verb].eject { |r| r.match(path) } + def determine_route(verb, path) + found = routes[verb].eject { |r| r.match(path) } + found ||= routes[404] + end + + def call(env) + request = Rack::Request.new(env) + route = determine_route( + request.request_method.downcase.to_sym, + request.path_info + ) + begin + [200, {}, route.block.call] + rescue => e + [500, {}, (routes[500] || Error).call] + end end class Route diff --git a/test/dispatching_test.rb b/test/dispatching_test.rb index ce396e3..f9da676 100644 --- a/test/dispatching_test.rb +++ b/test/dispatching_test.rb @@ -1,14 +1,50 @@ require File.dirname(__FILE__) + '/helper' + + context "Dispatching" do + include Sinatra::Test::Methods + + setup do + Sinatra.routes.clear + end + specify "should return the correct block" do Sinatra.routes[:get] << r = Sinatra::Route.new('/') do 'main' end - result = Sinatra.determine_event(:get, '/') + result = Sinatra.determine_route(:get, '/') result.block.should.be r.block end + specify "should return custom 404" do + Sinatra.routes[404] = r = Proc.new { 'custom 404' } + result = Sinatra.determine_route(:get, '/') + result.should.be r + end + + specify "should give custom 500 if error when called" do + Sinatra.routes[500] = r = Proc.new { 'custom 500' } + + Sinatra.routes[:get] << Sinatra::Route.new('/') do + raise 'asdf' + end + + get_it '/' + + body.should.equal 'custom 500' + end + + specify "should give standard 500 if error when called" do + Sinatra.routes[:get] << Sinatra::Route.new('/') do + raise 'asdf' + end + + get_it '/' + + body.should.match /^asdf/ + end + end diff --git a/test/helper.rb b/test/helper.rb index 26d6941..7b10f85 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -1,3 +1,44 @@ require File.dirname(__FILE__) + "/../lib/sinatra" require 'test/spec' require 'mocha' + + +module Sinatra + + module Test + + module Methods + + def get_it(path, params = {}) + @request = Rack::MockRequest.new(Sinatra) + @response = @request.get(path, :input => params.to_params) + end + + def post_it(path, params = {}) + @request = Rack::MockRequest.new(Sinatra) + @response = @request.post(path, :input => params.to_params) + end + + def put_it(path, params = {}) + @request = Rack::MockRequest.new(Sinatra) + @response = @request.put(path, :input => params.to_params) + end + + def delete_it(path, params = {}) + @request = Rack::MockRequest.new(Sinatra) + @response = @request.delete(path, :input => params.to_params) + end + + def follow! + get_it(@response.location) + end + + def method_missing(name, *args) + @response.send(name, *args) + end + + end + + end + +end -- 2.11.4.GIT