From 3b491e00ab034a1666375ff818e9a3375a4608e3 Mon Sep 17 00:00:00 2001 From: "blake.mizerany@gmail.com" Date: Tue, 11 Sep 2007 01:14:18 +0000 Subject: [PATCH] * custom 404 * bug fixes * refactoring --- lib/sinatra.rb | 7 ++++--- lib/sinatra/dispatcher.rb | 2 +- lib/sinatra/environment.rb | 16 ++++++++++++++++ lib/sinatra/event.rb | 16 ++++++++++------ lib/sinatra/options.rb | 7 ++++++- lib/sinatra/server.rb | 22 +++------------------- test/helper.rb | 3 ++- test/sinatra/dispatcher_test.rb | 32 +++++++++++++++++++++++++++++++- test/sinatra/event_test.rb | 15 +++++++++++++-- 9 files changed, 86 insertions(+), 34 deletions(-) create mode 100644 lib/sinatra/environment.rb diff --git a/lib/sinatra.rb b/lib/sinatra.rb index 7d022580..3b2acded 100644 --- a/lib/sinatra.rb +++ b/lib/sinatra.rb @@ -37,6 +37,7 @@ Sinatra::Loader.load_files Dir.glob(SINATRA_ROOT + '/lib/sinatra/core_ext/*.rb') Sinatra::Loader.load_files Dir.glob(SINATRA_ROOT + '/lib/sinatra/*.rb') Sinatra::Loader.load_files Dir.glob(SINATRA_ROOT + '/vendor/*/init.rb') -at_exit do - Sinatra::Server.new.start unless Sinatra::Server.running -end +Sinatra::Environment.setup! +Sinatra::Irb.start! if Sinatra::Options.console + +at_exit { Sinatra::Server.new.start unless Sinatra::Server.running } diff --git a/lib/sinatra/dispatcher.rb b/lib/sinatra/dispatcher.rb index 2b0ebe13..24d8b670 100644 --- a/lib/sinatra/dispatcher.rb +++ b/lib/sinatra/dispatcher.rb @@ -9,7 +9,7 @@ module Sinatra end def call(env) - Loader.reload! if Options.environment == :production + Loader.reload! if Options.environment == :development @request = Rack::Request.new(env) diff --git a/lib/sinatra/environment.rb b/lib/sinatra/environment.rb new file mode 100644 index 00000000..705088f9 --- /dev/null +++ b/lib/sinatra/environment.rb @@ -0,0 +1,16 @@ +module Sinatra + module Environment + extend self + + def setup! + Options.parse!(ARGV) + set_loggers + end + + def set_loggers(logger = Logger.new(open(Options.log_file, 'w'))) + [Server, EventContext, Event, Dispatcher].each do |klass| + klass.logger = logger + end + end + end +end diff --git a/lib/sinatra/event.rb b/lib/sinatra/event.rb index 70585850..b28e2343 100644 --- a/lib/sinatra/event.rb +++ b/lib/sinatra/event.rb @@ -4,7 +4,7 @@ module Sinatra extend self def reset! - @events.clear + @events.clear if @events end def events @@ -15,14 +15,18 @@ module Sinatra (@events ||= []) << event end - def determine_event(verb, path) - EventManager.events.detect(method(:not_found)) do |e| + def determine_event(verb, path, if_nil = :present_error) + events.detect(method(if_nil)) do |e| e.path == path && e.verb == verb end end + def present_error + determine_event(:get, 404, :not_found) + end + def not_found - Event.new(:get, nil) do + Event.new(:get, nil, false) do status 404 views_dir SINATRA_ROOT + '/files' @@ -105,11 +109,11 @@ module Sinatra attr_reader :path, :verb - def initialize(verb, path, &block) + def initialize(verb, path, register = true, &block) @verb = verb @path = path @block = block - EventManager.register_event(self) + EventManager.register_event(self) if register end def attend(request) diff --git a/lib/sinatra/options.rb b/lib/sinatra/options.rb index 4ef7c2c7..ef591a51 100644 --- a/lib/sinatra/options.rb +++ b/lib/sinatra/options.rb @@ -9,12 +9,13 @@ module Sinatra attr_with_default :console, nil def parse!(args) + return if @environment == :test OptionParser.new do |opts| opts.on '-p port', '--port port', 'Set the port (default is 4567)' do |port| @port = port end opts.on '-e environment', 'Set the environment (default if development)' do |env| - @environment = env + @environment = env.intern end opts.on '-c', '--console', 'Run in console mode' do @console = true @@ -29,5 +30,9 @@ module Sinatra def log_file File.dirname($0) + ('/%s.log' % environment) end + + def set_environment(env) + @environment = env + end end end diff --git a/lib/sinatra/server.rb b/lib/sinatra/server.rb index 7f75418b..bf4bac85 100644 --- a/lib/sinatra/server.rb +++ b/lib/sinatra/server.rb @@ -9,17 +9,13 @@ module Sinatra def start begin - setup_environment - - Irb.start! if Options.console - tail_thread = tail(Options.log_file) Rack::Handler::Mongrel.run(Dispatcher.new, :Port => Options.port) do |server| - logger.info "== Sinatra has taken the stage on port #{server.port}!" + puts "== Sinatra has taken the stage on port #{server.port}!" trap("INT") do server.stop self.class.running = false - logger.info "\n== Sinatra has ended his set (crowd applauds)" + puts "\n== Sinatra has ended his set (crowd applauds)" end end self.class.running = true @@ -31,19 +27,7 @@ module Sinatra end private - - def setup_environment - Options.parse!(ARGV) - set_loggers - end - - def set_loggers - logger = Logger.new(open(Options.log_file, 'w')) - [Server, EventContext, Event, Dispatcher].each do |klass| - klass.logger = logger - end - end - + def tail(log_file) FileUtils.touch(log_file) cursor = File.size(log_file) diff --git a/test/helper.rb b/test/helper.rb index ea06c561..d8a77f13 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -9,7 +9,8 @@ require File.dirname(__FILE__) + '/../lib/sinatra' end Sinatra::Server.running = true +Sinatra::Options.set_environment :test class Test::Unit::TestCase - include TestMethods + include Sinatra::TestMethods end diff --git a/test/sinatra/dispatcher_test.rb b/test/sinatra/dispatcher_test.rb index fc96fb4b..0faad104 100644 --- a/test/sinatra/dispatcher_test.rb +++ b/test/sinatra/dispatcher_test.rb @@ -1,6 +1,10 @@ require File.dirname(__FILE__) + '/../helper' describe "When a dispatcher receives a request" do + + before(:each) do + Sinatra::EventManager.reset! + end it "should attend to the event" do @@ -14,7 +18,7 @@ describe "When a dispatcher receives a request" do text.should.equal 'this is the index as a get' headers['Content-Type'].should.equal 'text/html' - post_it "/test" + post_it "/" status.should.equal 404 text.scan("Not Found :: Sinatra").size.should.equal 1 @@ -26,5 +30,31 @@ describe "When a dispatcher receives a request" do text.scan("Not Found :: Sinatra").size.should.equal 1 end + + it "should use custom error pages if present" do + Sinatra::Event.new(:get, 404) do + body 'custom 404' + end + + get_it('/laksdjf').should.equal 'custom 404' + end + + it "should reload app files unless in production" do + Sinatra::Event.new(:get, '/') {} + + Sinatra::Options.expects(:environment).returns(:production) + Sinatra::Loader.expects(:reload!).never + get_it '/' + + Sinatra::Options.expects(:environment).returns(:development) + Sinatra::Loader.expects(:reload!) + get_it '/' + end + + it "should not register not_found (otherwise we'll have a newone in the array for every error)" do + Sinatra::EventManager.events.size.should.equal 0 + get_it '/blake' + Sinatra::EventManager.events.size.should.equal 0 + end end \ No newline at end of file diff --git a/test/sinatra/event_test.rb b/test/sinatra/event_test.rb index c7efda56..0e95ab6a 100644 --- a/test/sinatra/event_test.rb +++ b/test/sinatra/event_test.rb @@ -3,15 +3,26 @@ require File.dirname(__FILE__) + '/../helper' describe "Event" do it "should return 500 if exception thrown" do - set_logger stub_everything + Sinatra::Environment.set_loggers stub_everything event = Sinatra::Event.new(:get, nil) do raise 'whaaaa!' end - result = event.attend(stub_everything) + result = event.attend(stub_everything(:params => {})) result.status.should.equal 500 end + it "custom error if present" do + Sinatra::Environment.set_loggers stub_everything + + event = Sinatra::Event.new(:get, 404) do + body 'custom 404' + end + + Sinatra::EventManager.expects(:not_found).never + Sinatra::EventManager.determine_event(:get, '/sdf') + end + end