Changeset 1079

Show
Ignore:
Timestamp:
12/11/07 05:09:01 (1 year ago)
Author:
has.s..@gmail.com
Message:

Extracted url and other general methods out of ControllerMixin? into GeneralControllerMixin?

This is so that PartController? and MailController? can generate url's in their views.

Files:

Legend:

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

    r1017 r1079  
    5252  autoload :ViewContextMixin, 'merb/mixins/view_context' 
    5353  autoload :WebControllerMixin, 'merb/mixins/web_controller' 
     54  autoload :GeneralControllerMixin, 'merb/mixins/general_controller' 
    5455  autoload :Caching, 'merb/caching' 
    5556  autoload :AbstractController, 'merb/abstract_controller' 
  • trunk/lib/merb/abstract_controller.rb

    r1051 r1079  
    33  class AbstractController                  
    44    include Merb::RenderMixin 
     5    include Merb::GeneralControllerMixin 
    56     
    67    class_inheritable_accessor :before_filters 
  • trunk/lib/merb/controller.rb

    r1056 r1079  
    206206    end 
    207207     
     208    private 
     209     
     210    # This method is here to overwrite the one in the general_controller mixin 
     211    # The method ensures that when a url is generated with a hash, it contains a controller 
     212    def get_controller_for_url_generation(options) 
     213      controller = options[:controller] || params[:controller] 
     214      controller = params[:controller] if controller == :current 
     215      controller 
     216    end 
     217     
    208218  end   
    209219   
  • trunk/lib/merb/mail_controller.rb

    r1074 r1079  
    250250    end 
    251251     
     252    protected 
     253    def route 
     254      @base_controller.route if @base_controller 
     255    end 
     256 
     257    private 
     258    # This method is here to overwrite the one in the general_controller mixin 
     259    # The method ensures that when a url is generated with a hash, it contains a controller 
     260    def get_controller_for_url_generation(opts) 
     261      puts @base_controller.params[:controller] if @base_controller 
     262      controller = opts[:controller] || ( @base_controller.params[:controller] if @base_controller) 
     263       raise "No Controller Specified for url()" unless controller 
     264       controller 
     265    end 
     266     
     267     
    252268  end 
    253269end 
  • trunk/lib/merb/mixins/controller.rb

    r1073 r1079  
    33  module ControllerMixin 
    44     
    5     # Returns a URL according to the defined route.  Accepts the path and 
    6     # an options hash.  The path specifies the route requested.  The options  
    7     # hash fills in the dynamic parts of the route. 
    8     # 
    9     # Merb routes can often be one-way; if they use a regex to define 
    10     # the route, then knowing the controller & action won't be enough 
    11     # to reverse-generate the route.  However, if you use the default 
    12     # /controller/action/id?query route, +default_route+ can generate 
    13     # it for you. 
    14     # 
    15     # For easy reverse-routes that use a Regex, be sure to also add 
    16     # a name to the route, so +url+ can find it. 
    17     #  
    18     # Nested resources such as: 
    19     # 
    20     #  r.resources :blogposts do |post| 
    21     #    post.resources :comments 
    22     #  end 
    23     # 
    24     # Provide the following routes: 
    25     # 
    26     #   [:blogposts, "/blogposts"] 
    27     #   [:blogpost, "/blogposts/:id"] 
    28     #   [:edit_blogpost, "/blogposts/:id/edit"] 
    29     #   [:new_blogpost, "/blogposts/new"] 
    30     #   [:custom_new_blogpost, "/blogposts/new/:action"] 
    31     #   [:comments, "/blogposts/:blogpost_id/comments"] 
    32     #   [:comment, "/blogposts/:blogpost_id/comments/:id"] 
    33     #   [:edit_comment, "/blogposts/:blogpost_id/comments/:id/edit"] 
    34     #   [:new_comment, "/blogposts/:blogpost_id/comments/new"] 
    35     #   [:custom_new_comment, "/blogposts/:blogpost_id/comments/new/:action"] 
    36     # 
    37     # 
    38     # ==== Parameters 
    39     # 
    40     # :route_name: - Symbol that represents a named route that you want to use, such as +:edit_post+. 
    41     # :new_params: - Parameters to be passed to the generated URL, such as the +id+ for a record to edit. 
    42     # 
    43     # ==== Examples 
    44     # 
    45     #  @post = Post.find(1) 
    46     #  @comment = @post.comments.find(1) 
    47     # 
    48     #  url(:blogposts)                                    # => /blogposts 
    49     #  url(:new_post)                                     # => /blogposts/new 
    50     #  url(:blogpost, @post)                              # => /blogposts/1 
    51     #  url(:edit_blogpost, @post)                         # => /blogposts/1/edit 
    52     #  url(:custom_new_blogpost, :action => 'alternate')  # => /blogposts/new/alternate 
     5    # # Returns a URL according to the defined route.  Accepts the path and 
     6    # # an options hash.  The path specifies the route requested.  The options  
     7    # # hash fills in the dynamic parts of the route. 
     8    # # 
     9    # # Merb routes can often be one-way; if they use a regex to define 
     10    # # the route, then knowing the controller & action won't be enough 
     11    # # to reverse-generate the route.  However, if you use the default 
     12    # # /controller/action/id?query route, +default_route+ can generate 
     13    # # it for you. 
     14    # # 
     15    # # For easy reverse-routes that use a Regex, be sure to also add 
     16    # # a name to the route, so +url+ can find it. 
     17    # #  
     18    # # Nested resources such as: 
     19    # # 
     20    # #  r.resources :blogposts do |post| 
     21    # #    post.resources :comments 
     22    # #  end 
     23    # # 
     24    # # Provide the following routes: 
     25    # # 
     26    # #   [:blogposts, "/blogposts"] 
     27    # #   [:blogpost, "/blogposts/:id"] 
     28    # #   [:edit_blogpost, "/blogposts/:id/edit"] 
     29    # #   [:new_blogpost, "/blogposts/new"] 
     30    # #   [:custom_new_blogpost, "/blogposts/new/:action"] 
     31    # #   [:comments, "/blogposts/:blogpost_id/comments"] 
     32    # #   [:comment, "/blogposts/:blogpost_id/comments/:id"] 
     33    # #   [:edit_comment, "/blogposts/:blogpost_id/comments/:id/edit"] 
     34    # #   [:new_comment, "/blogposts/:blogpost_id/comments/new"] 
     35    # #   [:custom_new_comment, "/blogposts/:blogpost_id/comments/new/:action"] 
     36    # # 
     37    # # 
     38    # # ==== Parameters 
     39    # # 
     40    # # :route_name: - Symbol that represents a named route that you want to use, such as +:edit_post+. 
     41    # # :new_params: - Parameters to be passed to the generated URL, such as the +id+ for a record to edit. 
     42    # # 
     43    # # ==== Examples 
     44    # # 
     45    # #  @post = Post.find(1) 
     46    # #  @comment = @post.comments.find(1) 
     47    # # 
     48    # #  url(:blogposts)                                    # => /blogposts 
     49    # #  url(:new_post)                                     # => /blogposts/new 
     50    # #  url(:blogpost, @post)                              # => /blogposts/1 
     51    # #  url(:edit_blogpost, @post)                         # => /blogposts/1/edit 
     52    # #  url(:custom_new_blogpost, :action => 'alternate')  # => /blogposts/new/alternate 
     53    # #    
     54    # #  url(:comments, :blogpost => @post)         # => /blogposts/1/comments 
     55    # #  url(:new_comment, :blogpost => @post)      # => /blogposts/1/comments/new 
     56    # #  url(:comment, @comment)                    # => /blogposts/1/comments/1 
     57    # #  url(:edit_comment, @comment)               # => /blogposts/1/comments/1/edit 
     58    # #  url(:custom_new_comment, :blogpost => @post) 
     59    # # 
     60    # #  url(:page => 2)                            # => /posts/show/1?page=2 
     61    # #  url(:new_post, :page => 3)                 # => /posts/new?page=3 
     62    # #  url('/go/here', :page => 3)                # => /go/here?page=3 
     63    # # 
     64    # #  url(:controller => "welcome")              # => /welcome 
     65    # #  url(:controller => "welcome", :action => "greet") 
     66    # #                                             # => /welcome/greet 
     67    # # 
     68    # def url(route_name = nil, new_params = {}) 
     69    #   if route_name.is_a?(Hash) 
     70    #     new_params = route_name 
     71    #     route_name = nil 
     72    #   end 
    5373    #    
    54     #  url(:comments, :blogpost => @post)         # => /blogposts/1/comments 
    55     #  url(:new_comment, :blogpost => @post)      # => /blogposts/1/comments/new 
    56     #  url(:comment, @comment)                    # => /blogposts/1/comments/1 
    57     #  url(:edit_comment, @comment)               # => /blogposts/1/comments/1/edit 
    58     #  url(:custom_new_comment, :blogpost => @post) 
    59     # 
    60     #  url(:page => 2)                            # => /posts/show/1?page=2 
    61     #  url(:new_post, :page => 3)                 # => /posts/new?page=3 
    62     #  url('/go/here', :page => 3)                # => /go/here?page=3 
    63     # 
    64     #  url(:controller => "welcome")              # => /welcome 
    65     #  url(:controller => "welcome", :action => "greet") 
    66     #                                             # => /welcome/greet 
    67     # 
    68     def url(route_name = nil, new_params = {}) 
    69       if route_name.is_a?(Hash) 
    70         new_params = route_name 
    71         route_name = nil 
    72       end 
    73        
    74       url = if new_params.respond_to?(:keys) && route_name.nil? && 
    75         !(new_params.keys & [:controller, :action, :id]).empty? 
    76           url_from_default_route(new_params) 
    77         elsif route_name.nil? && !route.regexp? 
    78           url_from_route(route, new_params) 
    79         elsif route_name.nil? 
    80           request.path + (new_params.empty? ? "" : "?" + params_to_query_string(new_params)) 
    81         elsif route_name.is_a?(Symbol) 
    82           url_from_route(route_name, new_params) 
    83         elsif route_name.is_a?(String) 
    84           route_name + (new_params.empty? ? "" : "?" + params_to_query_string(new_params)) 
    85         else 
    86           raise "URL not generated: #{route_name.inspect}, #{new_params.inspect}" 
    87         end 
    88       url = MerbHandler.path_prefix + url if MerbHandler.path_prefix 
    89       url 
    90     end 
    91  
    92     def url_from_route(symbol, new_params = {}) 
    93       if new_params.respond_to?(:new_record?) && new_params.new_record? 
    94         symbol = "#{symbol}".singularize.to_sym 
    95         new_params = {} 
    96       end 
    97       route = symbol.is_a?(Symbol) ? Merb::Router.named_routes[symbol] : symbol 
    98       unless route 
    99         raise InternalServerError, "URL could not be constructed. Route symbol not found: #{symbol.inspect}"  
    100       end 
    101       path = route.generate(new_params, params) 
    102       keys = route.symbol_segments 
    103       if new_params.is_a? Hash 
    104         if ext = format_extension(new_params) 
    105           new_params.delete(:format) 
    106           path += "." + ext 
    107         end 
    108         extras = new_params.reject{ |k, v| keys.include?(k) } 
    109         path += "?" + params_to_query_string(extras) unless extras.empty? 
    110       end 
    111       path 
    112     end 
    113      
    114     # this is pretty ugly, but it works.  TODO: make this cleaner 
    115     def url_from_default_route(new_params) 
    116       query_params = new_params.reject do |k,v| 
    117         [:controller, :action, :id, :format].include?(k) 
    118       end 
    119       controller = new_params[:controller] || params[:controller] 
    120       controller = params[:controller] if controller == :current 
    121       url = "/#{controller}" 
    122       if new_params[:action] || new_params[:id] || 
    123                 new_params[:format] || !query_params.empty? 
    124         action = new_params[:action] || params[:action] 
    125         url += "/#{action}" 
    126       end 
    127       if new_params[:id] 
    128         url += "/#{new_params[:id]}" 
    129       end 
    130       if format = new_params[:format] 
    131         format = params[:format] if format == :current 
    132         url += ".#{format}" 
    133       end 
    134       unless query_params.empty? 
    135         url += "?" + params_to_query_string(query_params) 
    136       end 
    137       url 
    138     end 
    139  
    140     protected 
    141  
    142     # Creates query string from params, supporting nested arrays and hashes. 
    143     # ==== Example 
    144     #   params_to_query_string(:user => {:filter => {:name => "quux*"}, :order => ["name"]}) 
    145     #   # => user[filter][name]=quux%2A&user[order][]=name 
    146     def params_to_query_string(value, prefix = nil) 
    147       case value 
    148       when Array 
    149         value.map { |v| 
    150           params_to_query_string(v, "#{prefix}[]") 
    151         } * "&" 
    152       when Hash 
    153         value.map { |k, v| 
    154           params_to_query_string(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k)) 
    155         } * "&" 
    156       else 
    157         "#{prefix}=#{escape(value)}" 
    158       end 
    159     end 
    160      
    161     # +format_extension+ dictates when named route URLs generated by the url 
    162     # method will have a file extension. It will return either false or the format  
    163     # extension to append. 
    164     # 
    165     # ==== Configuration Options 
    166     # 
    167     # By default, non-HTML URLs will be given an extension. It is posible  
    168     # to override this behaviour by setting +:use_format_in_urls+ in your  
    169     # Merb config (merb.yml) to either true/false. 
    170     # 
    171     # +true+  Results in all URLs (even HTML) being given extensions. 
    172     #         This effect is often desirable when you have many formats and dont 
    173     #         wish to treat .html any differently than any other format.  
    174     # +false+ Results in no URLs being given extensions and +format+ 
    175     #         gets treated just like any other param (default). 
    176     # 
    177     # ==== Method parameters 
    178     #  
    179     # +new_params+ - New parameters to be appended to the URL 
    180     # 
    181     # ==== Examples 
    182     # 
    183     #   url(:post, :id => post, :format => 'xml') 
    184     #   # => /posts/34.xml 
    185     # 
    186     #   url(:accounts, :format => 'yml') 
    187     #   # => /accounts.yml 
    188     # 
    189     #   url(:edit_product, :id => 3, :format => 'html') 
    190     #   # => /products/3 
    191     # 
    192     def format_extension(new_params={}) 
    193       use_format = Merb::Server.config[:use_format_in_urls] 
    194       if use_format.nil? 
    195         prms = params.merge(new_params) 
    196         use_format = prms[:format] != 'html' && prms[:format] 
    197       end 
    198       use_format 
    199     end 
     74    #   url = if new_params.respond_to?(:keys) && route_name.nil? && 
     75    #     !(new_params.keys & [:controller, :action, :id]).empty? 
     76    #       url_from_default_route(new_params) 
     77    #     elsif route_name.nil? && !route.regexp? 
     78    #       url_from_route(route, new_params) 
     79    #     elsif route_name.nil? 
     80    #       request.path + (new_params.empty? ? "" : "?" + params_to_query_string(new_params)) 
     81    #     elsif route_name.is_a?(Symbol) 
     82    #       url_from_route(route_name, new_params) 
     83    #     elsif route_name.is_a?(String) 
     84    #       route_name + (new_params.empty? ? "" : "?" + params_to_query_string(new_params)) 
     85    #     else 
     86    #       raise "URL not generated: #{route_name.inspect}, #{new_params.inspect}" 
     87    #     end 
     88    #   url = MerbHandler.path_prefix + url if MerbHandler.path_prefix 
     89    #   url 
     90    # end 
     91    #  
     92    # def url_from_route(symbol, new_params = {}) 
     93    #   if new_params.respond_to?(:new_record?) && new_params.new_record? 
     94    #     symbol = "#{symbol}".singularize.to_sym 
     95    #     new_params = {} 
     96    #   end 
     97    #   route = symbol.is_a?(Symbol) ? Merb::Router.named_routes[symbol] : symbol 
     98    #   unless route 
     99    #     raise InternalServerError, "URL could not be constructed. Route symbol not found: #{symbol.inspect}"  
     100    #   end 
     101    #   path = route.generate(new_params, params) 
     102    #   keys = route.symbol_segments 
     103    #   if new_params.is_a? Hash 
     104    #     if ext = format_extension(new_params) 
     105    #       new_params.delete(:format) 
     106    #       path += "." + ext 
     107    #     end 
     108    #     extras = new_params.reject{ |k, v| keys.include?(k) } 
     109    #     path += "?" + params_to_query_string(extras) unless extras.empty? 
     110    #   end 
     111    #   path 
     112    # end 
     113    #  
     114    # # this is pretty ugly, but it works.  TODO: make this cleaner 
     115    # def url_from_default_route(new_params) 
     116    #   query_params = new_params.reject do |k,v| 
     117    #     [:controller, :action, :id, :format].include?(k) 
     118    #   end 
     119    #   controller = new_params[:controller] || params[:controller] 
     120    #   controller = params[:controller] if controller == :current 
     121    #   url = "/#{controller}" 
     122    #   if new_params[:action] || new_params[:id] || 
     123    #             new_params[:format] || !query_params.empty? 
     124    #     action = new_params[:action] || params[:action] 
     125    #     url += "/#{action}" 
     126    #   end 
     127    #   if new_params[:id] 
     128    #     url += "/#{new_params[:id]}" 
     129    #   end 
     130    #   if format = new_params[:format] 
     131    #     format = params[:format] if format == :current 
     132    #     url += ".#{format}" 
     133    #   end 
     134    #   unless query_params.empty? 
     135    #     url += "?" + params_to_query_string(query_params) 
     136    #   end 
     137    #   url 
     138    # end 
     139    #  
     140    # protected 
     141    #  
     142    # # Creates query string from params, supporting nested arrays and hashes. 
     143    # # ==== Example 
     144    # #   params_to_query_string(:user => {:filter => {:name => "quux*"}, :order => ["name"]}) 
     145    # #   # => user[filter][name]=quux%2A&user[order][]=name 
     146    # def params_to_query_string(value, prefix = nil) 
     147    #   case value 
     148    #   when Array 
     149    #     value.map { |v| 
     150    #       params_to_query_string(v, "#{prefix}[]") 
     151    #     } * "&" 
     152    #   when Hash 
     153    #     value.map { |k, v| 
     154    #       params_to_query_string(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k)) 
     155    #     } * "&" 
     156    #   else 
     157    #     "#{prefix}=#{escape(value)}" 
     158    #   end 
     159    # end 
     160    #  
     161    # # +format_extension+ dictates when named route URLs generated by the url 
     162    # # method will have a file extension. It will return either false or the format  
     163    # # extension to append. 
     164    # # 
     165    # # ==== Configuration Options 
     166    # # 
     167    # # By default, non-HTML URLs will be given an extension. It is posible  
     168    # # to override this behaviour by setting +:use_format_in_urls+ in your  
     169    # # Merb config (merb.yml) to either true/false. 
     170    # # 
     171    # # +true+  Results in all URLs (even HTML) being given extensions. 
     172    # #         This effect is often desirable when you have many formats and dont 
     173    # #         wish to treat .html any differently than any other format.  
     174    # # +false+ Results in no URLs being given extensions and +format+ 
     175    # #         gets treated just like any other param (default). 
     176    # # 
     177    # # ==== Method parameters 
     178    # #  
     179    # # +new_params+ - New parameters to be appended to the URL 
     180    # # 
     181    # # ==== Examples 
     182    # # 
     183    # #   url(:post, :id => post, :format => 'xml') 
     184    # #   # => /posts/34.xml 
     185    # # 
     186    # #   url(:accounts, :format => 'yml') 
     187    # #   # => /accounts.yml 
     188    # # 
     189    # #   url(:edit_product, :id => 3, :format => 'html') 
     190    # #   # => /products/3 
     191    # # 
     192    # def format_extension(new_params={}) 
     193    #   use_format = Merb::Server.config[:use_format_in_urls] 
     194    #   if use_format.nil? 
     195    #     prms = params.merge(new_params) 
     196    #     use_format = prms[:format] != 'html' && prms[:format] 
     197    #   end 
     198    #   use_format 
     199    # end 
    200200     
    201201    # Renders the block given as a parameter using chunked 
     
    352352    end 
    353353   
    354     # Creates an MD5 hashed token based on the current time. 
    355     # 
    356     # ==== Example 
    357     #   make_token 
    358     #   # => "b9a82e011694cc13a4249731b9e83cea"  
    359     # 
    360     def make_token 
    361       require 'digest/md5' 
    362       Digest::MD5.hexdigest("#{inspect}#{Time.now}#{rand}") 
    363     end 
    364  
    365     # Escapes the string representation of +obj+ and escapes 
    366     # it for use in XML. 
    367     # 
    368     # ==== Parameter 
    369     # 
    370     # +obj+ - The object to escape for use in XML. 
    371     # 
    372     def escape_xml(obj) 
    373       obj.to_s.gsub(/[&<>"']/) { |s| Merb::Const::ESCAPE_TABLE[s] } 
    374     end 
    375     alias h escape_xml 
    376     alias html_escape escape_xml 
    377    
    378     # Escapes +s+ for use in a URL. 
    379     # 
    380     # ==== Parameter 
    381     # 
    382     # +s+ - String to URL escape. 
    383     # 
    384     def escape(s) 
    385       Mongrel::HttpRequest.escape(s) 
    386     end 
    387    
    388     # Unescapes a string (i.e., reverse URL escaping). 
    389     # 
    390     # ==== Parameter  
    391     # 
    392     # +s+ - String to unescape. 
    393     # 
    394     def unescape(s) 
    395       Mongrel::HttpRequest.unescape(s) 
    396     end 
     354    # # Creates an MD5 hashed token based on the current time. 
     355    # # 
     356    # # ==== Example 
     357    # #   make_token 
     358    # #   # => "b9a82e011694cc13a4249731b9e83cea"  
     359    # # 
     360    # def make_token 
     361    #   require 'digest/md5' 
     362    #   Digest::MD5.hexdigest("#{inspect}#{Time.now}#{rand}") 
     363    # end 
     364    #  
     365    # # Escapes the string representation of +obj+ and escapes 
     366    # # it for use in XML. 
     367    # # 
     368    # # ==== Parameter 
     369    # # 
     370    # # +obj+ - The object to escape for use in XML. 
     371    # # 
     372    # def escape_xml(obj) 
     373    #   obj.to_s.gsub(/[&<>"']/) { |s| Merb::Const::ESCAPE_TABLE[s] } 
     374    # end 
     375    # alias h escape_xml 
     376    # alias html_escape escape_xml 
     377    #    
     378    # # Escapes +s+ for use in a URL. 
     379    # # 
     380    # # ==== Parameter 
     381    # # 
     382    # # +s+ - String to URL escape. 
     383    # # 
     384    # def escape(s) 
     385    #   Mongrel::HttpRequest.escape(s) 
     386    # end 
     387    #    
     388    # # Unescapes a string (i.e., reverse URL escaping). 
     389    # # 
     390    # # ==== Parameter  
     391    # # 
     392    # # +s+ - String to unescape. 
     393    # # 
     394    # def unescape(s) 
     395    #   Mongrel::HttpRequest.unescape(s) 
     396    # end 
    397397   
    398398  end 
  • trunk/lib/merb/mixins/web_controller.rb

    r1047 r1079  
    2828      @web_controller.response 
    2929    end     
     30     
     31    def route 
     32      request.route 
     33    end 
    3034      
    3135  end 
  • trunk/lib/merb/part_controller.rb

    r908 r1079  
    1616      @_body 
    1717    end     
     18     
     19    private  
     20     
     21    # This method is here to overwrite the one in the general_controller mixin 
     22    # The method ensures that when a url is generated with a hash, it contains a controller 
     23    def get_controller_for_url_generation(opts) 
     24       controller = opts[:controller] || @web_controller.params[:controller] 
     25       raise "No Controller Specified for url()" unless controller 
     26       controller 
     27    end 
    1828  end 
    1929end     
  • trunk/spec/merb/controller_spec.rb

    r895 r1079  
    1717 
    1818describe Merb::Controller, "url generator tests" do 
     19   
     20  it_should_behave_like "class with general url generation" 
     21   
    1922  def new_url_controller(route, params = {:action => 'show', :controller => 'Test'}) 
    2023    request = OpenStruct.new 
     
    2730  end 
    2831   
    29   before(:all) do 
    30     Merb::Router.prepare do |r| 
    31       @resource_routes = r.resources(:blogs) 
    32       r.resources(:gardens) do |gardens| 
    33         @nested_resource = gardens.resources :flowers 
    34       end 
    35       @test_route = r.match("/the/:place/:goes/here").to(:controller => "Test", :action => "show").name(:test) 
    36       @default_route = r.default_routes 
    37     end 
    38   end 
     32  # before(:all) do 
     33  #   Merb::Router.prepare do |r| 
     34  #     @resource_routes = r.resources(:blogs) 
     35  #     r.resources(:gardens) do |gardens| 
     36  #       @nested_resource = gardens.resources :flowers 
     37  #     end 
     38  #     @test_route = r.match("/the/:place/:goes/here").to(:controller => "Test", :action => "show").name(:test) 
     39  #     @default_route = r.default_routes 
     40  #   end 
     41  # end 
    3942   
    40   it "should generate a url from a route using a hash" do 
    41     c = new_url_controller(@test_route, :place => "1") 
    42     c.url_from_route(@test_route, :goes => "g").should == "/the/1/g/here" 
    43   end 
     43  # it "should generate a url from a route using a hash" do 
     44  #   c = new_url_controller(@test_route, :place => "1") 
     45  #   c.url_from_route(@test_route, :goes => "g").should == "/the/1/g/here" 
     46  # end 
    4447 
    45   it "should generate a url from a route using an object" do 
    46     c = new_url_controller(@test_route, :place => "2") 
    47     obj = OpenStruct.new(:goes => "elsewhere") 
    48     c.url_from_route(@test_route, obj).should == "/the/2/elsewhere/here" 
    49   end 
     48  # it "should generate a url from a route using an object" do 
     49  #   c = new_url_controller(@test_route, :place => "2") 
     50  #   obj = OpenStruct.new(:goes => "elsewhere") 
     51  #   c.url_from_route(@test_route, obj).should == "/the/2/elsewhere/here" 
     52  # end 
    5053 
    51   it "should generate a url and tack extra params on as a query string" do 
    52     c = new_url_controller(@test_route, :place => "1") 
    53     c.url_from_route(@test_route, :goes => "g", :page => 2).should == "/the/1/g/here?page=2" 
    54   end 
     54  # it "should generate a url and tack extra params on as a query string" do 
     55  #   c = new_url_controller(@test_route, :place => "1") 
     56  #   c.url_from_route(@test_route, :goes => "g", :page => 2).should == "/the/1/g/here?page=2" 
     57  # end 
    5558   
    56   it "should generate a url directly from a hash using the current route as a default" do 
    57     c = new_url_controller(@test_route, :goes => "swimmingly") 
    58     c.url(:place => "provo").should == "/the/provo/swimmingly/here" 
    59   end 
     59  # it "should generate a url directly from a hash using the current route as a default" do 
     60  #   c = new_url_controller(@test_route, :goes => "swimmingly") 
     61  #   c.url(:place => "provo").should == "/the/provo/swimmingly/here" 
     62  # end 
    6063   
    61   it "should generate a default route url with just :controller" do 
    62     c = new_url_controller(@default_route) 
    63     c.url(:controller => "welcome").should == "/welcome" 
    64   end 
     64  # it "should generate a default route url with just :controller" do 
     65  #   c = new_url_controller(@default_route) 
     66  #   c.url(:controller => "welcome").should == "/welcome" 
     67  # end 
    6568 
    6669  it "should generate a default route url with just :action" do 
     
    7477  end 
    7578 
    76   it 'should generate urls from nested resources' do 
    77     c = new_url_controller(@nested_resource, :garden => 5) 
    78     c.url(:flower, :garden_id => 1, :id => 3).should == "/gardens/1/flowers/3" 
    79   end 
     79  # it 'should generate urls from nested resources' do 
     80  #   c = new_url_controller(@nested_resource, :garden => 5) 
     81  #   c.url(:flower, :garden_id => 1, :id => 3).should == "/gardens/1/flowers/3" 
     82  # end 
    8083 
    8184  it "should generate a default route url with an extra param" do 
     
    106109  end   
    107110   
    108   it "should generate a default route url with all options" do 
    109     c = new_url_controller(@default_route, :controller => "foo", :action => "bar") 
    110     c.url(:controller => "foo", :action => "bar", :id => "baz", :format => :js, :monkey => "quux").should == "/foo/bar/baz.js?monkey=quux" 
    111   end 
    112    
     111  # it "should generate a default route url with all options" do 
     112  #   c = new_url_controller(@default_route, :controller => "foo", :action => "bar") 
     113  #   c.url(:controller => "foo", :action => "bar", :id => "baz", :format => :js, :monkey => "quux").should == "/foo/bar/baz.js?monkey=quux" 
     114  # end 
     115  #  
    113116  it "should handle nested nested and more nested hashes and arrays" do 
    114117    c = new_url_controller(@default_route, :controller => "foo", :action => "bar") 
     
    118121  end 
    119122   
    120   it "should handle an object as the second arg" do 
    121     c = new_url_controller(@resource_routes, :controller => "blogs", :action => "show") 
    122     blog = mock("blog") 
    123     blog.should_receive(:id).once.and_return(7) 
    124     url = c.url(:blog, blog) 
    125     url.should == "/blogs/7" 
    126   end 
     123  # it "should handle an object as the second arg" do 
     124  #   c = new_url_controller(@resource_routes, :controller => "blogs", :action => "show") 
     125  #   blog = mock("blog") 
     126  #   blog.should_receive(:id).once.and_return(7) 
     127  #   url = c.url(:blog, blog) 
     128  #   url.should == "/blogs/7" 
     129  # end 
    127130 
    128   it "should point to /blogs/:blog_id if @blog is not new_record" do 
    129     c = new_url_controller(@resource_routes, :controller => "blogs", :action => "index") 
    130     blog = mock("blog") 
    131     blog.should_receive(:id).once.and_return(7) 
    132     blog.should_receive(:new_record?).once.and_return(false) 
    133     url = c.url(:blog, blog) 
    134     url.should == "/blogs/7" 
    135   end 
     131  # it "should point to /blogs/:blog_id if @blog is not new_record" do 
     132  #   c = new_url_controller(@resource_routes, :controller => "blogs", :action => "index") 
     133  #   blog = mock("blog") 
     134  #   blog.should_receive(:id).once.and_return(7) 
     135  #   blog.should_receive(:new_record?).once.and_return(false) 
     136  #   url = c.url(:blog, blog) 
     137  #   url.should == "/blogs/7" 
     138  # end 
    136139 
    137   it "should point to /blogs/ if @blog is new_record" do 
    138     c = new_url_controller(@resource_routes, :controller => "blogs", :action => "index") 
    139     blog = mock("blog") 
    140     blog.should_receive(:new_record?).once.and_return(true) 
    141     url = c.url(:blog, blog) 
    142     url.should == "/blogs/" 
    143   end 
     140  # it "should point to /blogs/ if @blog is new_record" do 
     141  #   c = new_url_controller(@resource_routes, :controller => "blogs", :action => "index") 
     142  #   blog = mock("blog") 
     143  #   blog.should_receive(:new_record?).once.and_return(true) 
     144  #   url = c.url(:blog, blog) 
     145  #   url.should == "/blogs/" 
     146  # end 
    144147end 
  • trunk/spec/merb/mail_controller_spec.rb

    r986 r1079  
    144144   
    145145end 
     146 
     147describe "Merb::MailController with url generation" do 
     148   
     149  it_should_behave_like "class with general url generation" 
     150  it_should_behave_like "non routeable controller with url mixin" 
     151   
     152  def new_url_controller(route, params = {:action => 'show', :controller => 'Test'}) 
     153    request = OpenStruct.new 
     154    request.route = route 
     155    request.params = params 
     156    response = OpenStruct.new 
     157    response.read = "" 
     158     
     159    @controller = Merb::Controller.build(request, response) 
     160    TestMailController.new(params, @controller) 
     161  end 
     162   
     163  it "should raise an error if no controller is specified and the base controller is not set" do 
     164    c = new_url_controller(@default_route, {})     
     165    lambda do 
     166      the_url = c.url(:action => "bar") 
     167    end.should raise_error 
     168  end 
     169   
     170  it "should use the base controller when it is set to generate a url when no :controller option is specified" do 
     171    c = new_url_controller(@defualt_route, :controller => "foo") 
     172    lambda do 
     173      the_url = c.url(:action => "bar") 
     174      the_url.should == "/foo/bar" 
     175    end.should_not raise_error     
     176  end 
     177end 
  • trunk/spec/merb/part_controller_spec.rb

    r904 r1079  
    9191   
    9292end   
     93 
     94describe "A Merb Part Controller with urls" do 
     95   
     96  it_should_behave_like "class with general url generation" 
     97  it_should_behave_like "non routeable controller with url mixin" 
     98   
     99  def new_url_controller(route, params = {:action => 'show', :controller => 'Test'}) 
     100    request = OpenStruct.new 
     101    request.route = route 
     102    request.params = params 
     103    response = OpenStruct.new 
     104    response.read = "" 
     105     
     106    @controller = Merb::Controller.build(request, response) 
     107    TodoPart.new(@controller) 
     108  end 
     109   
     110  it "should use the web_controllers type if no controller is specified" do 
     111    c = new_url_controller(@default_route, :controller => "my_controller") 
     112    the_url = c.url(:action => "bar") 
     113    the_url.should == "/my_controller/bar" 
     114  end 
     115   
     116  it "should raise an error if the web_controller's params[:controller] is not set" do 
     117    c = new_url_controller(@default_route, {}) 
     118    lambda do 
     119      the_url = c.url(:action => "bar") 
     120      the_url.should == "/my_controller/bar" 
     121    end.should raise_error 
     122  end 
     123   
     124end 
  • trunk/spec/spec_helper.rb

    r1077 r1079  
    1313 
    1414FIXTURES = File.expand_path(File.join(File.dirname(__FILE__), 'fixtures')) 
     15 
     16require File.join(File.dirname(__FILE__), "spec_helpers", "url_shared_behaviour") 
    1517 
    1618Spec::Runner.configure do |config| 
  • trunk/spec/spec_helpers/url_shared_behaviour.rb

    r895 r1079  
    1 require 'ostruct' 
    2 require File.dirname(__FILE__) + '/../spec_helper' 
    3  
    4 describe "Merb::Controller" do 
    5    
    6   # not sure what this tests 
    7   # it "should instantiate" do 
    8   #   c = new_controller 
    9   #   @request.env.should == c.request.env 
    10   # end 
    11    
    12   it "should have a default layout of application.rhtml" do 
    13     c = new_controller 
    14     c._layout.should == :application 
    15   end 
    16 end 
    17  
    18 describe Merb::Controller, "url generator tests" do 
    19   def new_url_controller(route, params = {:action => 'show', :controller => 'Test'}) 
    20     request = OpenStruct.new 
    21     request.route = route 
    22     request.params = params 
    23     response = OpenStruct.new 
    24     response.read = "" 
    25      
    26     Merb::Controller.build(request, response) 
    27   end 
     1describe "class with general url generation", :shared => true do 
    282   
    293  before(:all) do 
     
    3711    end 
    3812  end 
    39    
     13 
     14 
    4015  it "should generate a url from a route using a hash" do 
    4116    c = new_url_controller(@test_route, :place => "1") 
    4217    c.url_from_route(@test_route, :goes => "g").should == "/the/1/g/here" 
    4318  end 
    44  
     19   
    4520  it "should generate a url from a route using an object" do 
    4621    c = new_url_controller(@test_route, :place => "2") 
     
    4823    c.url_from_route(@test_route, obj).should == "/the/2/elsewhere/here" 
    4924  end 
    50  
     25   
    5126  it "should generate a url and tack extra params on as a query string" do 
    5227    c = new_url_controller(@test_route, :place => "1") 
     
    6338    c.url(:controller => "welcome").should == "/welcome" 
    6439  end 
    65  
    66   it "should generate a default route url with just :action" do 
    67     c = new_url_controller(@default_route, :controller => "foo") 
    68     c.url(:action => "baz").should == "/foo/baz" 
    69   end 
    7040   
    71   it "should generate a default route url with just :id" do 
    72     c = new_url_controller(@default_route, :controller => "foo", :action => "bar") 
    73     c.url(:id => "23").should == "/foo/bar/23" 
    74   end 
    75  
    7641  it 'should generate urls from nested resources' do 
    7742    c = new_url_controller(@nested_resource, :garden => 5) 
    7843    c.url(:flower, :garden_id => 1, :id => 3).should == "/gardens/1/flowers/3" 
    7944  end 
    80  
    81   it "should generate a default route url with an extra param" do 
    82     c = new_url_controller(@default_route, :controller => "foo", :action => "bar") 
    83     c.url(:controller => :current, :monkey => "quux").should == "/foo/bar?monkey=quux" 
    84   end 
    85  
    86   it "should generate a default route url with extra params" do 
    87     c = new_url_controller(@default_route, :controller => "foo", :action => "bar") 
    88     url = c.url(:controller => :current, :monkey => "quux", :cow => "moo") 
    89     url.should match(%r{/foo/bar?.*monkey=quux}) 
    90     url.should match(%r{/foo/bar?.*cow=moo}) 
    91   end 
    92  
    93   it "should generate a default route url with extra params and an array" do 
    94     c = new_url_controller(@default_route, :controller => "foo", :action => "bar") 
    95     c.url(:controller => :current, :monkey => [1,2]).should == "/foo/bar?monkey[]=1&monkey[]=2" 
    96   end 
    9745   
    98   it "should generate a default route url with extra params and a hash" do 
    99     c = new_url_controller(@default_route, :controller => "foo", :action => "bar") 
    100     c.url(:controller => :current, :animals => {:cow => "moo"}).should == "/foo/bar?animals[cow]=moo" 
    101   end 
    102  
    103   it "should generate a default route url with :action and :format" do 
    104     c = new_url_controller(@default_route, :controller => "foo", :action => "bar") 
    105     c.url(:action => :recent, :format => :txt).should == "/foo/recent.txt" 
    106   end   
     46  # it "should generate a default route url with an extra param" do 
     47  #   c = new_url_controller(@default_route, :controller => "foo", :action => "bar") 
     48  #   c.url(:controller => :current, :monkey => "quux").should == "/foo/bar?monkey=quux" 
     49  # end 
    10750   
    10851  it "should generate a default route url with all options" do 
    10952    c = new_url_controller(@default_route, :controller => "foo", :action => "bar") 
    11053    c.url(:controller => "foo", :action => "bar", :id => "baz", :format => :js, :monkey => "quux").should == "/foo/bar/baz.js?monkey=quux" 
    111   end 
    112    
    113   it "should handle nested nested and more nested hashes and arrays" do 
    114     c = new_url_controller(@default_route, :controller => "foo", :action => "bar") 
    115     url = c.url(:controller => :current, :user => {:filter => {:name => "quux*"}, :order => ["name"]}) 
    116     url.should match(%r{/foo/bar?.*user\[filter\]\[name\]=quux%2A}) 
    117     url.should match(%r{/foo/bar?.*user\[order\]\[\]=name}) 
    11854  end 
    11955   
     
    12561    url.should == "/blogs/7" 
    12662  end 
    127  
     63   
    12864  it "should point to /blogs/:blog_id if @blog is not new_record" do 
    12965    c = new_url_controller(@resource_routes, :controller => "blogs", :action => "index") 
     
    13470    url.should == "/blogs/7" 
    13571  end 
    136  
     72   
    13773  it "should point to /blogs/ if @blog is new_record" do 
    13874    c = new_url_controller(@resource_routes, :controller => "blogs", :action => "index") 
     
    14379  end 
    14480end 
     81 
     82describe "non routeable controller with url mixin", :shared => true do 
     83   
     84  before(:all) do 
     85    Merb::Router.prepare do |r| 
     86      @resource_routes = r.resources(:blogs) 
     87      r.resources(:gardens) do |gardens| 
     88        @nested_resource = gardens.resources :flowers 
     89      end 
     90      @test_route = r.match("/the/:place/:goes/here").to(:controller => "Test", :action => "show").name(:test) 
     91      @default_route = r.default_routes 
     92    end 
     93  end 
     94   
     95  it "should route when given a controller and an action" do 
     96    c = new_url_controller(@default_route, :controller => "blah") 
     97    the_url = c.url(:controller => "foo", :action => "bar") 
     98    the_url.should == "/foo/bar" 
     99  end 
     100   
     101  it "should generate a route when only a controller is given" do 
     102    c = new_url_controller(@default_route, :controller => "blah") 
     103    the_url = c.url(:controller => "foo") 
     104    the_url.should == "/foo" 
     105  end 
     106   
     107  it "should generate a route with controller action and extra options" do 
     108    c = new_url_controller(@default_route, :controller => "blah") 
     109    the_url = c.url(:controller => "foo", :action => "bar", :cool => "false") 
     110    the_url.should == "/foo/bar?cool=false" 
     111  end   
     112