Changeset 648

Show
Ignore:
Timestamp:
09/18/07 07:34:49 (1 year ago)
Author:
duane.johns..@gmail.com
Message:

Add _subclasses to Controller class so that the dispatcher can know in advance what constitutes a valid controller class. This will permit gems and plugins to have controllers and views since the dispatcher (Request class) no longer relies on a file-system check to see if the controller file exists where it expects. Also fixed the DOS bug with to_const_string (thanks chris) (closes #181)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/lib/merb/controller.rb

    r640 r648  
    88  # puts that into params as well. 
    99  class Controller < AbstractController 
     10    cattr_accessor :_subclasses 
     11    self._subclasses = [] 
    1012     
    1113    class_inheritable_accessor :_session_id_key, :_session_expiry 
     
    1820     
    1921    class << self 
     22      def inherited(klass) 
     23        _subclasses << klass.to_s 
     24        super 
     25      end 
     26       
    2027      def callable_actions 
    2128        @callable_actions ||= Set.new(public_instance_methods - hidden_actions) 
  • trunk/lib/merb/core_ext/string.rb

    r595 r648  
    22 
    33class String 
     4  class InvalidPathConversion < Exception; end 
    45   
    56  def escape_regexp 
     
    2223    input = StringScanner.new(self) 
    2324    until input.eos? 
    24       if input.scan(/([a-z][a-zA-Z\d]*)(_|$)/) 
     25      if input.scan(/([a-z][a-zA-Z\d]*)(_|$|\/)/) 
    2526        new_string << input[1].capitalize 
    26       elsif input.scan(/([a-z][a-zA-Z\d]*)\//) 
    27         new_string << input[1].capitalize << "::" 
     27        new_string << "::" if input[2] == '/' 
     28      else 
     29        raise InvalidPathConversion, self 
    2830      end 
    2931    end 
  • trunk/lib/merb/request.rb

    r640 r648  
    126126     
    127127    def controller_class 
    128       path = "#{MERB_ROOT}/app/controllers/#{controller_name}.rb" 
    129128      cnt = controller_name.to_const_string 
    130129       
    131       if !File.exist?(path
    132         raise ControllerExceptions::NotFound, "Bad controller! #{cnt}
    133       end unless $TESTING 
     130      if !Controller._subclasses.include?(cnt
     131        raise ControllerExceptions::NotFound, "Controller '#{cnt}' not found
     132      end 
    134133       
    135134      begin 
  • trunk/specs/merb/merb_core_ext_spec.rb

    r517 r648  
    394394    "snake_case/path/with_several_parts".to_const_string.should == "SnakeCase::Path::WithSeveralParts" 
    395395  end 
    396 end 
     396   
     397  it "should raise an error rather than freeze when trying to convert bad Paths/12Like/-this" do 
     398    Timeout::timeout(1) do 
     399      lambda do 
     400        "Paths/12Like/-this".to_const_string 
     401      end.should raise_error(String::InvalidPathConversion) 
     402    end.should_not raise_error(Timeout::Error) 
     403  end 
     404end 
  • trunk/specs/merb/merb_dispatch_spec.rb

    r640 r648  
    3535  it "should handle request: GET /foo/bar and return Foo#bar" do 
    3636    controller, action = request(:get, '/foo/bar') 
     37    e = controller.params[:exception] 
    3738    controller.class.should == Foo 
    3839    action.should == "bar" 
  • trunk/specs/merb/merb_request_spec.rb

    r643 r648  
    22 
    33describe Merb::Request do 
     4  include Mocha::SetupAndTeardown 
     5   
     6  class GoodPosts < Merb::Controller 
     7    def show() end 
     8  end 
    49   
    510  before(:all) do 
     11    setup_stubs 
    612    @in = Merb::Test::FakeRequest.new 
     13    Merb::Request.any_instance.stubs(:route_params).returns({}) 
     14  end 
     15   
     16  after(:all) do 
     17    teardown_stubs 
    718  end 
    819   
     
    171182    request.params[:title].should == "hello" 
    172183  end 
     184 
     185  it "should not raise a NotFound exception when the controller class exists" do 
     186    @in['REQUEST_URI'] = "/good_posts/show/1" 
     187    @in['REQUEST_METHOD'] = 'GET' 
     188    @in['CONTENT_TYPE'] = "application/x-www-form-urlencoded" 
     189    request = Merb::Request.new(@in) 
     190    request.expects(:controller_name).returns("good_posts") 
     191    request.controller_name.should == "good_posts" 
     192    lambda { request.controller_class }.should_not raise_error(Merb::ControllerExceptions::NotFound) 
     193  end 
     194   
     195  it "should raise a NotFound exception when the controller does not exist" do 
     196    @in['REQUEST_URI'] = "/bad_posts/show/1" 
     197    @in['REQUEST_METHOD'] = 'GET' 
     198    @in['CONTENT_TYPE'] = "application/x-www-form-urlencoded" 
     199    request = Merb::Request.new(@in) 
     200    request.expects(:controller_name).returns("bad_posts") 
     201    request.controller_name.should == "bad_posts" 
     202    lambda { request.controller_class }.should raise_error(Merb::ControllerExceptions::NotFound) 
     203  end 
    173204end