Changeset 680

Show
Ignore:
Timestamp:
09/24/07 07:03:31 (1 year ago)
Author:
r.@tinyclouds.org
Message:

spec'd out Action and Router

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/ry_routes/lib/merb.rb

    r632 r680  
    3030  autoload :AbstractController, 'merb/abstract_controller' 
    3131  autoload :Const, 'merb/constants' 
     32  autoload :Action, 'merb/action' 
    3233  autoload :Controller, 'merb/controller' 
    3334  autoload :Dispatcher, 'merb/dispatcher' 
  • branches/ry_routes/lib/merb/action.rb

    r678 r680  
    11module Merb 
    22  class Action 
     3    include Merb::ControllerExceptions 
     4    class_inheritable_accessor :acceptable_methods 
     5    self.acceptable_methods = [:get, :head] # default acceptable methods 
    36    class << self 
    4       def base_url 
    5         name.split('::').join('/') 
     7       
     8      def method(*m) 
     9        self.acceptable_methods = m 
    610      end 
    711       
    8       def dispatch(request, status = 200) 
    9         unless @@acceptable_methods.include? request.method 
    10           raise NotAcceptable, "#{name} does not respond to #{request.method}" 
     12      def dispatch(request) 
     13        unless acceptable_methods.include?(request.method) 
     14          raise(ControllerExceptions::NotAcceptable,  
     15            "Action #{name} does not respond to HTTP method #{request.method}") 
    1116        end 
    1217         
    1318        action = new(request) 
    14         action.build 
     19        action.setup 
    1520         
    1621        # negotiate which content type to use 
    17         extension = request.accept_extensions.find do |ext|  
     22        extension = request.acceptable_extensions.find do |ext|  
    1823          responds_to.include?(ext) 
     24        end 
     25         
     26        unless extension 
     27          raise(ControllerExceptions::NotAcceptable,  
     28            "Action #{name} does not respond the requested content types") 
    1929        end 
    2030         
     
    2434        # render the action 
    2535        unless request.method == :head 
    26           action.body = action.send("to_" + extension
     36          action.body = action.send("respond_" + extension.to_s
    2737        end 
    2838         
     
    3545      # the list is based on instance methods defined as "to_extension" 
    3646      def responds_to 
    37         @@responds_to ||= instance_methods.grep(/^to_(.+)/).map { |x| x[3..-1] } 
    38       end 
    39       private :responds_to 
    40        
    41       def method(*m) 
    42         @@acceptable_methods = [:get, :head].include?(m) ? [:get, :head] : [m] 
     47        @@responds_to ||= begin 
     48          Const::TYPES.keys.find_all { |ext| method_defined?("respond_" + ext) } 
     49        end 
    4350      end 
    4451    end 
     
    4855    end 
    4956     
    50     def build 
     57    def setup 
    5158    end 
    5259     
     
    7178    end 
    7279     
     80    def status 
     81      @_status ||= 200 
     82    end 
     83     
     84    def status=(s) 
     85      @_status = s 
     86    end 
     87     
     88    def body=(b) 
     89      @_body = b  
     90    end 
     91 
    7392    def body 
    74       @_body 
     93      @_body  
    7594    end 
    7695  end 
  • branches/ry_routes/lib/merb/constants.rb

    r678 r680  
    1313      :yaml => %w[application/x-yaml text/yaml], 
    1414      :text => %w[text/plain], 
     15      :json => %w[application/json], 
    1516      :html => %w[text/html application/xhtml+xml application/html], 
    1617      :xml  => %w[application/xml text/xml application/x-xml], 
  • branches/ry_routes/lib/merb/core_ext/module.rb

    r678 r680  
    11class Module 
     2   
     3  def tree 
     4    submodules.inject({}) do |hash, sub| 
     5      hash.update sub => sub.tree 
     6    end 
     7  end 
    28   
    39  def submodules 
     
    612      c if c.kind_of?(Module) 
    713    end.compact 
     14  end 
     15   
     16  def nest(m) 
     17    const_set(m.name.split('::').last, m) 
    818  end 
    919   
  • branches/ry_routes/lib/merb/router.rb

    r678 r680  
    1 module Actions 
     1module Root 
    22end 
    33 
    44module Merb 
    5   class SimpleRouter 
    6      
     5  class Router 
    76    class << self 
    87       
    98      def table 
    10         @@table ||= module_route_table(Actions
     9        @@table ||= module_route_table(Root
    1110      end 
    1211       
     
    1413        hash = {} 
    1514        mod.submodules.each do |sub| 
    16           hash[sub.base_url] = sub if sub.respond_to?(:base_url) 
    17           hash.update module_route_table(sub) 
     15          hash[sub.name.split('::').last] =  
     16          if sub.respond_to?(:superclass) and sub.superclass == Merb::Action 
     17            sub 
     18          else 
     19            module_route_table(sub) 
     20          end 
    1821        end 
    1922        hash 
     
    2124       
    2225      def match(path) 
    23         # this can be optimized a lot. 
     26        # TODO: normalize path 
    2427        sections = path.split('/') 
    25         sections.length.times do  
    26           j = sections.join('/') 
    27           return table[j] if table.has_key?(j) 
    28           sections.pops 
     28        sections.shift # remove initial "" 
     29        h = sections.inject(table) do |h, sec| 
     30          return nil unless h.respond_to?(:[]) 
     31          h[sec] 
     32        end 
     33        if h.respond_to?(:superclass) and h.superclass == Merb::Action 
     34          h 
     35        else 
     36          nil 
    2937        end 
    3038      end 
  • branches/ry_routes/specs/spec_helper.rb

    r627 r680  
    1313 
    1414FIXTURES = File.expand_path(File.join(File.dirname(__FILE__), 'fixtures')) 
    15  
    1615 
    1716# Creates a new controller, e.g. 
  • branches/ry_routes/target_api.rb

    r678 r680  
    1  
    21module Actions::Products 
    32  before Index do |req| 
    4     session[:user].admin? 
     3    req.session[:user].admin? 
    54  end 
    65   
    76  class Index < Action 
    8     def build 
     7    def setup 
    98      @products = Product.paginate(params[:page] || 1) 
    109    end 
    1110     
    12     def to_json 
     11    def respond_json 
    1312      @products.to_json 
    1413    end 
    1514     
    16     def to_html 
    17       render 
    18     end 
     15    # By default Action implements this behavior 
     16    # so no need to state it explicitly 
     17    # 
     18    # def respond_html 
     19    #   render 
     20    # end 
    1921  end 
    2022 
    2123  class Update < Action 
    2224    method :post 
    23     extra_route ':id' 
    24     def build 
     25    url_params ':id' 
     26    def setup 
    2527      @product = Product.find(req.params[:id]) 
    2628    end