diff options
59 files changed, 348 insertions, 1765 deletions
diff --git a/actionpack/lib/action_controller/assertions/action_pack_assertions.rb b/actionpack/lib/action_controller/assertions/action_pack_assertions.rb index 7d27240244..c26941cd6b 100644 --- a/actionpack/lib/action_controller/assertions/action_pack_assertions.rb +++ b/actionpack/lib/action_controller/assertions/action_pack_assertions.rb @@ -141,7 +141,7 @@ module Test #:nodoc: end end end - + # ensure our redirection url is an exact match def assert_redirect_url(url=nil, message=nil) assert_redirect(message) @@ -158,36 +158,6 @@ module Test #:nodoc: assert_block(msg) { response.redirect_url_match?(pattern) } end - # -- routing assertions -------------------------------------------------- - - # Asserts that the routing of the given path is handled correctly and that the parsed options match. - # Also verifies that the provided options can be used to generate the provided path. - def assert_routing(path, options, defaults={}, extras={}, message=nil) - defaults[:controller] ||= options[:controller] # Assume given controller, - request = ActionController::TestRequest.new({}, {}, nil) - request.path_parameters = defaults - - ActionController::Routing::Routes.reload if ActionController::Routing::Routes.empty? # Load routes.rb if it hasn't been loaded. - - generated_path, found_extras = ActionController::Routing::Routes.generate(defaults.merge(options), request) - generated_path = generated_path.join('/') - msg = build_message(message, "found extras <?>, not <?>", found_extras, extras) - assert_block(msg) { found_extras == extras } - - msg = build_message(message, "The generated path <?> did not match <?>", generated_path, path) - assert_block(msg) { path == generated_path } - - request = ActionController::TestRequest.new({}, {}, nil) - request.path = path - ActionController::Routing::Routes.recognize!(request) - - expected_options = options.clone - extras.each {|k,v| expected_options.delete k} - - msg = build_message(message, "The recognized options <?> did not match <?>", request.path_parameters, expected_options) - assert_block(msg) { request.path_parameters == expected_options } - end - # -- template assertions ------------------------------------------------ # ensure that a template object with the given name exists diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index a30f3b94d7..cfcd46d985 100755 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -13,13 +13,6 @@ module ActionController #:nodoc: end class MissingTemplate < ActionControllerError #:nodoc: end - class RoutingError < ActionControllerError - attr_reader :failures - def initialize(message, failures=[]) - super(message) - @failures = failures - end - end class UnknownAction < ActionControllerError #:nodoc: end class MissingFile < ActionControllerError #:nodoc: @@ -212,12 +205,6 @@ module ActionController #:nodoc: # should instead be implemented in the controller to determine when debugging screens should be shown. @@consider_all_requests_local = true cattr_accessor :consider_all_requests_local - - # Enable or disable the collection of failure information for RoutingErrors. - # This information can be extremely useful when tweaking custom routes, but is - # pointless once routes have been tested and verified. - @@debug_routes = true - cattr_accessor :debug_routes # Template root determines the base from which template references will be made. So a call to render("test/template") # will be converted to "#{template_root}/test/template.rhtml". @@ -274,14 +261,6 @@ module ActionController #:nodoc: def controller_name Inflector.underscore(controller_class_name.sub(/Controller/, "")) end - - # Convert the class name from something like "OneModule::TwoModule::NeatController" to "one_module/two_module/neat". - def controller_path - components = self.name.to_s.split('::').collect { |name| name.underscore } - components[-1] = $1 if /^(.*)_controller$/ =~ components[-1] - components.shift if components.first == 'controllers' # Transitional conditional to accomodate root Controllers module - components.join('/') - end end public @@ -358,6 +337,10 @@ module ActionController #:nodoc: end end + def module_name + @params["module"] + end + # Converts the class name from something like "OneModule::TwoModule::NeatController" to "NeatController". def controller_class_name self.class.controller_class_name @@ -708,7 +691,7 @@ module ActionController #:nodoc: end def default_template_name(default_action_name = action_name) - "#{self.class.controller_path}/#{default_action_name}" + module_name ? "#{module_name}/#{controller_name}/#{default_action_name}" : "#{controller_name}/#{default_action_name}" end end end diff --git a/actionpack/lib/action_controller/cgi_process.rb b/actionpack/lib/action_controller/cgi_process.rb index c301b322e5..92b19fbf18 100644 --- a/actionpack/lib/action_controller/cgi_process.rb +++ b/actionpack/lib/action_controller/cgi_process.rb @@ -46,16 +46,8 @@ module ActionController #:nodoc: super() end - def query_string - return @cgi.query_string unless @cgi.query_string.nil? || @cgi.query_string.empty? - parts = env['REQUEST_URI'].split('?') - parts.shift - return parts.join('?') - end - def query_parameters - qs = self.query_string - qs.empty? ? {} : CGIMethods.parse_query_parameters(query_string) + @cgi.query_string ? CGIMethods.parse_query_parameters(@cgi.query_string) : {} end def request_parameters diff --git a/actionpack/lib/action_controller/helpers.rb b/actionpack/lib/action_controller/helpers.rb index a97fd93410..1201d31946 100644 --- a/actionpack/lib/action_controller/helpers.rb +++ b/actionpack/lib/action_controller/helpers.rb @@ -48,22 +48,25 @@ module ActionController #:nodoc: def helper(*args, &block) args.flatten.each do |arg| case arg - when Module - add_template_helper(arg) - when String, Symbol - file_name = arg.to_s.underscore + '_helper' - class_name = file_name.camelize - - begin - require_dependency(file_name) - rescue LoadError => load_error - requiree = / -- (.*?)(\.rb)?$/.match(load_error).to_a[1] - raise LoadError, requiree == file_name ? "Missing helper file helpers/#{file_name}.rb" : "Can't load file: #{requiree}" + when Module + add_template_helper(arg) + when String, Symbol + file_name = Inflector.underscore(arg.to_s.downcase) + '_helper' + class_name = Inflector.camelize(file_name) + begin + require_dependency(file_name) + rescue LoadError => load_error + requiree = / -- (.*?)(\.rb)?$/.match(load_error).to_a[1] + if requiree == file_name + raise LoadError, "Missing helper file helpers/#{file_name}.rb" + else + raise LoadError, "Can't load file: #{requiree}" end - - add_template_helper(class_name.constantize) - else - raise ArgumentError, 'helper expects String, Symbol, or Module argument' + end + raise ArgumentError, "Missing #{class_name} module in helpers/#{file_name}.rb" unless Object.const_defined?(class_name) + add_template_helper(Object.const_get(class_name)) + else + raise ArgumentError, 'helper expects String, Symbol, or Module argument' end end @@ -92,7 +95,7 @@ module ActionController #:nodoc: def inherited(child) inherited_without_helper(child) begin - child.helper(child.controller_path) + child.helper(child.controller_name) rescue ArgumentError, LoadError # No default helper available for this controller end diff --git a/actionpack/lib/action_controller/request.rb b/actionpack/lib/action_controller/request.rb index 2ac6081a96..3e2344c3cb 100755 --- a/actionpack/lib/action_controller/request.rb +++ b/actionpack/lib/action_controller/request.rb @@ -3,7 +3,7 @@ module ActionController class AbstractRequest # Returns both GET and POST parameters in a single hash. def parameters - @parameters ||= request_parameters.merge(query_parameters).merge(path_parameters).with_indifferent_access + @parameters ||= request_parameters.update(query_parameters) end def method @@ -73,7 +73,7 @@ module ActionController end def request_uri - (%r{^\w+\://[^/]+(/.*|$)$} =~ env['REQUEST_URI']) ? $1 : env['REQUEST_URI'] # Remove domain, which webrick puts into the request_uri. + env['REQUEST_URI'] end def protocol @@ -85,7 +85,7 @@ module ActionController end def path - path = request_uri ? request_uri.split('?').first : '' + request_uri ? request_uri.split('?').first : '' end def port @@ -100,16 +100,7 @@ module ActionController def host_with_port env['HTTP_HOST'] || host + port_string end - - def path_parameters=(parameters) - @path_parameters = parameters - @parameters = nil - end - def path_parameters - @path_parameters ||= {} - end - #-- # Must be implemented in the concrete request #++ diff --git a/actionpack/lib/action_controller/rescue.rb b/actionpack/lib/action_controller/rescue.rb index 9eb64ba7cc..eb7f614de0 100644 --- a/actionpack/lib/action_controller/rescue.rb +++ b/actionpack/lib/action_controller/rescue.rb @@ -48,11 +48,7 @@ module ActionController #:nodoc: # Overwrite to implement public exception handling (for requests answering false to <tt>local_request?</tt>). def rescue_action_in_public(exception) #:doc: - case exception - when RoutingError, UnknownAction then - render_text(IO.read(File.join(RAILS_ROOT, 'public', '404.html')), "404 Not Found") - else render_text "<html><body><h1>Application error (Rails)</h1></body></html>" - end + render_text "<html><body><h1>Application error (Rails)</h1></body></html>" end # Overwrite to expand the meaning of a local request in order to show local rescues on other occurences than @@ -114,21 +110,13 @@ module ActionController #:nodoc: rescues_path( case exception when MissingTemplate then "missing_template" - when RoutingError then "routing_error" when UnknownAction then "unknown_action" when ActionView::TemplateError then "template_error" - else raise ;"diagnostics" + else "diagnostics" end ) end - def response_code_for_rescue(exception) - case exception - when UnknownAction, RoutingError then "404 Page Not Found" - else "500 Internal Error" - end - end - def clean_backtrace(exception) exception.backtrace.collect { |line| Object.const_defined?(:RAILS_ROOT) ? line.gsub(RAILS_ROOT, "") : line } end diff --git a/actionpack/lib/action_controller/routing.rb b/actionpack/lib/action_controller/routing.rb deleted file mode 100644 index 39ce487e62..0000000000 --- a/actionpack/lib/action_controller/routing.rb +++ /dev/null @@ -1,260 +0,0 @@ -module ActionController - module Routing - ROUTE_FILE = defined?(RAILS_ROOT) ? File.expand_path(File.join(RAILS_ROOT, 'config', 'routes')) : nil - - class Route - attr_reader :defaults # The defaults hash - - def initialize(path, hash={}) - raise ArgumentError, "Second argument must be a hash!" unless hash.kind_of?(Hash) - @defaults = {} - @requirements = {} - self.items = path - hash.each do |k, v| - raise TypeError, "Hash may only contain symbols!" unless k.kind_of? Symbol - (@items.include?(k) ? @defaults : @requirements)[k] = v - end - - # Add in defaults for :action and :id. - [[:action, 'index'], [:id, nil]].each do |name, default| - @defaults[name] = default if @items.include?(name) && ! (@requirements.key?(name) || @defaults.key?(name)) - end - end - - # Generate a URL given the provided options. - # All values in options should be symbols. - # Returns the path and the unused names in a 2 element array. - # If generation fails, [nil, nil] is returned - # Generation can fail because of a missing value, or because an equality check fails. - # - # Generate urls will be as short as possible. If the last component of a url is equal to the default value, - # then that component is removed. This is applied as many times as possible. So, your index controller's - # index action will generate [] - def generate(options, defaults={}) - non_matching = @requirements.inject([]) {|a, (k, v)| ((options[k] || defaults[k]) == v) ? a : a << k} - return nil, "Options mismatch requirements: #{non_matching.join ', '}" unless non_matching.empty? - - used_names = @requirements.inject({}) {|hash, (k, v)| hash[k] = true; hash} - components = @items.collect do |item| - if item.kind_of? Symbol - used_names[item] = true - value = options[item] || defaults[item] || @defaults[item] - return nil, "#{item.inspect} was not given and has no default." if value.nil? && ! (@defaults.key?(item) && @defaults[item].nil?) # Don't leave if nil value. - defaults = {} unless defaults == {} || value == defaults[item] # Stop using defaults if this component isn't the same as the default. - value - else item - end - end - - @items.reverse_each do |item| # Remove default components from the end of the generated url. - break unless item.kind_of?(Symbol) && @defaults[item] == components.last - components.pop - end - - # If we have any nil components then we can't proceed. - # This might need to be changed. In some cases we may be able to return all componets after nil as extras. - missing = []; components.each_with_index {|c, i| missing << @items[i] if c.nil?} - return nil, "No values provided for component#{'s' if missing.length > 1} #{missing.join ', '} but values are required due to use of later components" unless missing.empty? # how wide is your screen? - - unused = (options.keys - used_names.keys).inject({}) do |unused, key| - unused[key] = options[key] if options[key] != @defaults[key] - unused - end - - components.collect! {|c| c.to_s} - components.unshift(components.shift + '/') if components.length == 1 && @items.first == :controller # Add '/' to controllers - - return components, unused - end - - # Recognize the provided path, returning a hash of recognized values, or [nil, reason] if the path isn't recognized. - # The path should be a list of component strings. - # Options is a hash of the ?k=v pairs - def recognize(components, options={}) - options = options.clone - components = components.clone - controller_class = nil - - @items.each do |item| - if item == :controller # Special case for controller - if components.empty? && @defaults[:controller] - controller_class, leftover = eat_path_to_controller(@defaults[:controller].split('/')) - raise RoutingError, "Default controller does not exist: #{@defaults[:controller]}" if controller_class.nil? || leftover.empty? == false - else - controller_class, remaining_components = eat_path_to_controller(components) - return nil, "No controller found at subpath #{components.join('/')}" if controller_class.nil? - components = remaining_components - end - options[:controller] = controller_class.controller_path - elsif item.kind_of? Symbol - value = components.shift || @defaults[item] - return nil, "No value or default for parameter #{item.inspect}" if value.nil? && ! (@defaults.key?(item) && @defaults[item].nil?) - options[item] = value - else - return nil, "No value available for component #{item.inspect}" if components.empty? - component = components.shift - return nil, "Value for component #{item.inspect} doesn't match #{component}" if component != item - end - end - - if controller_class.nil? && @requirements[:controller] # Load a default controller - controller_class, extras = eat_path_to_controller(@requirements[:controller].split('/')) - raise RoutingError, "Illegal controller path for route default: #{@requirements[:controller]}" unless controller_class && extras.empty? - options[:controller] = controller_class.controller_path - end - options = @requirements.merge(options) - - return nil, "Route recognition didn't find a controller class!" unless controller_class - return nil, "Unused components were left: #{components.join '/'}" unless components.empty? - options.delete_if {|k, v| v.nil?} # Remove nil values. - return controller_class, options - end - - def inspect - when_str = @requirements.empty? ? "" : " when #{@requirements.inspect}" - default_str = @defaults.empty? ? "" : " || #{@defaults.inspect}" - "<#{self.class.to_s} #{@items.collect{|c| c.kind_of?(String) ? c : c.inspect}.join('/').inspect}#{default_str}#{when_str}>" - end - - protected - # Find the controller given a list of path components. - # Return the controller class and the unused path components. - def eat_path_to_controller(path) - path.inject([Controllers, 1]) do |(mod, length), name| - name = name.camelize - controller_name = name + "Controller" - return mod.const_get(controller_name), path[length..-1] if mod.const_available? controller_name - return nil, nil unless mod.const_available? name - [mod.const_get(name), length + 1] - end - return nil, nil # Path ended, but no controller found. - end - - def items=(path) - items = path.split('/').collect {|c| (/^:(\w+)$/ =~ c) ? $1.intern : c} if path.kind_of?(String) # split and convert ':xyz' to symbols - items.shift if items.first == "" - items.pop if items.last == "" - @items = items - - # Verify uniqueness of each component. - @items.inject({}) do |seen, item| - if item.kind_of? Symbol - raise ArgumentError, "Illegal route path -- duplicate item #{item}\n #{path.inspect}" if seen.key? item - seen[item] = true - end - seen - end - end - end - - class RouteSet - def initialize - @routes = [] - end - - def add_route(route) - raise TypeError, "#{route.inspect} is not a Route instance!" unless route.kind_of?(Route) - @routes << route - end - def empty? - @routes.empty? - end - def each - @routes.each {|route| yield route} - end - - # Generate a path for the provided options - # Returns the path as an array of components and a hash of unused names - # Raises RoutingError if not route can handle the provided components. - # - # Note that we don't return the first generated path. We do this so that when a route - # generates a path from a subset of the available options we can keep looking for a - # route which can generate a path that uses more options. - # Note that we *do* return immediately if - def generate(options, request) - raise RoutingError, "There are no routes defined!" if @routes.empty? - options = options.symbolize_keys - defaults = request.path_parameters.symbolize_keys - expand_controller_path!(options, defaults) - - failures = [] - selected = nil - self.each do |route| - path, unused = route.generate(options, defaults) - if path.nil? - failures << [route, unused] if ActionController::Base.debug_routes - else - return path, unused if unused.empty? # Found a perfect route -- we're finished. - if selected.nil? || unused.length < selected.last.length - failures << [selected.first, "A better url than #{selected[1]} was found."] if selected - selected = [route, path, unused] - end - end - end - - return selected[1..-1] unless selected.nil? - raise RoutingError.new("Generation failure: No route for url_options #{options.inspect}, defaults: #{defaults.inspect}", failures) - end - - # Recognize the provided path. - # Raise RoutingError if the path can't be recognized. - def recognize!(request) - path = ((%r{^/?(.*)/?$} =~ request.path) ? $1 : request.path).split('/') - raise RoutingError, "There are no routes defined!" if @routes.empty? - - failures = [] - self.each do |route| - controller, options = route.recognize(path) - if controller.nil? - failures << [route, options] if ActionController::Base.debug_routes - else - options.each {|k, v| request.path_parameters[k] = CGI.unescape(v)} - return controller - end - end - - raise RoutingError.new("No route for path: #{path.join('/').inspect}", failures) - end - - def expand_controller_path!(options, defaults) - if options[:controller] - if /^\// =~ options[:controller] - options[:controller] = options[:controller][1..-1] - defaults.clear # Sending to absolute controller implies fresh defaults - else - relative_to = defaults[:controller] ? defaults[:controller].split('/')[0..-2].join('/') : '' - options[:controller] = relative_to.empty? ? options[:controller] : "#{relative_to}/#{options[:controller]}" - end - else - options[:controller] = defaults[:controller] - end - end - - def route(*args) - add_route(Route.new(*args)) - end - alias :connect :route - - def reload - begin require_dependency(ROUTE_FILE) - rescue LoadError, ScriptError => e - raise RoutingError, "Cannot load config/routes.rb:\n #{e.message}" - ensure # Ensure that there is at least one route: - connect(':controller/:action/:id', :action => 'index', :id => nil) if @routes.empty? - end - end - - def draw - @routes.clear - yield self - end - end - - def self.draw(*args, &block) - Routes.draw(*args) {|*args| block.call(*args)} - end - - Routes = RouteSet.new - #Routes.reload # Do this here, so that server will die on load if SyntaxError or whatnot. - end -end
\ No newline at end of file diff --git a/actionpack/lib/action_controller/scaffolding.rb b/actionpack/lib/action_controller/scaffolding.rb index 140df73972..9c1311efa3 100644 --- a/actionpack/lib/action_controller/scaffolding.rb +++ b/actionpack/lib/action_controller/scaffolding.rb @@ -149,7 +149,7 @@ module ActionController private def render#{suffix}_scaffold(action = caller_method_name(caller)) - if template_exists?("\#{self.class.controller_path}/\#{action}") + if template_exists?("\#{controller_name}/\#{action}") render_action(action) else @scaffold_class = #{class_name} diff --git a/actionpack/lib/action_controller/templates/rescues/routing_error.rhtml b/actionpack/lib/action_controller/templates/rescues/routing_error.rhtml deleted file mode 100644 index 82c01e10c9..0000000000 --- a/actionpack/lib/action_controller/templates/rescues/routing_error.rhtml +++ /dev/null @@ -1,8 +0,0 @@ -<h1>Routing Error</h1> -<p><%=h @exception.message %></p> -<% unless @exception.failures.empty? %><p> - <h2>Failure reasons:</h2> - <% @exception.failures.each do |route, reason| %> - <%=h route.inspect.gsub('\\', '') %> failed because <%=h reason.downcase %><br /> - <% end %> -</p><% end %> diff --git a/actionpack/lib/action_controller/test_process.rb b/actionpack/lib/action_controller/test_process.rb index 3223da198c..d4dfe7933d 100644 --- a/actionpack/lib/action_controller/test_process.rb +++ b/actionpack/lib/action_controller/test_process.rb @@ -31,8 +31,8 @@ module ActionController #:nodoc: class TestRequest < AbstractRequest #:nodoc: attr_accessor :cookies - attr_accessor :query_parameters, :request_parameters, :path, :session, :env - attr_accessor :host, :remote_addr + attr_accessor :query_parameters, :request_parameters, :session, :env + attr_accessor :host, :path, :request_uri, :remote_addr def initialize(query_parameters = nil, request_parameters = nil, session = nil) @query_parameters = query_parameters || {} @@ -58,28 +58,11 @@ module ActionController #:nodoc: @parameters = nil end - # Used to check AbstractRequest's request_uri functionality. - # Disables the use of @path and @request_uri so superclass can handle those. - def set_REQUEST_URI(value) - @env["REQUEST_URI"] = value - @request_uri = nil - @path = nil - end - def request_uri=(uri) @request_uri = uri @path = uri.split("?").first end - def request_uri - @request_uri || super() - end - - def path - @path || super() - end - - private def initialize_containers @env, @cookies = {}, {} @@ -254,7 +237,6 @@ module Test def process(action, parameters = nil, session = nil) @request.env['REQUEST_METHOD'] ||= "GET" @request.action = action.to_s - @request.path_parameters = { :controller => @controller.class.controller_path } @request.parameters.update(parameters) unless parameters.nil? @request.session = ActionController::TestSession.new(session) unless session.nil? @controller.process(@request, @response) diff --git a/actionpack/lib/action_controller/url_rewriter.rb b/actionpack/lib/action_controller/url_rewriter.rb index 3364262e4c..3451e6acc9 100644 --- a/actionpack/lib/action_controller/url_rewriter.rb +++ b/actionpack/lib/action_controller/url_rewriter.rb @@ -1,9 +1,10 @@ module ActionController # Rewrites URLs for Base.redirect_to and Base.url_for in the controller. class UrlRewriter #:nodoc: - RESERVED_OPTIONS = [:anchor, :params, :path_params, :only_path, :host, :protocol] - def initialize(request, parameters) - @request, @parameters = request, parameters + VALID_OPTIONS = [:action, :action_prefix, :action_suffix, :application_prefix, :module, :controller, :controller_prefix, :anchor, :params, :path_params, :id, :only_path, :overwrite_params, :host, :protocol ] + + def initialize(request, controller, action) + @request, @controller, @action = request, controller, action @rewritten_path = @request.path ? @request.path.dup : "" end @@ -21,7 +22,7 @@ module ActionController end def to_str - "#{@request.protocol}, #{@request.host_with_port}, #{@request.path}, #{@parameters[:controller]}, #{@parameters[:action]}, #{@request.parameters.inspect}" + "#{@request.protocol}, #{@request.host_with_port}, #{@request.path}, #{@controller}, #{@action}, #{@request.parameters.inspect}" end private @@ -47,14 +48,12 @@ module ActionController return rewritten_url end - def rewrite_path(options) - options = options.symbolize_keys - RESERVED_OPTIONS.each {|k| options.delete k} - - path, extras = Routing::Routes.generate(options, @request) - path = "/#{path.join('/')}" - path += build_query_string(extras) - + def rewrite_path(path, options) + include_id_in_path_params(options) + + path = rewrite_action(path, options) if options[:action] || options[:action_prefix] + path = rewrite_path_params(path, options) if options[:path_params] + path = rewrite_controller(path, options) if options[:controller] || options[:controller_prefix] return path end diff --git a/actionpack/lib/action_view/partials.rb b/actionpack/lib/action_view/partials.rb index bbb38778b7..f771f0a826 100644 --- a/actionpack/lib/action_view/partials.rb +++ b/actionpack/lib/action_view/partials.rb @@ -60,7 +60,7 @@ module ActionView if partial_path.include?('/') return File.dirname(partial_path), File.basename(partial_path) else - return controller.class.controller_path, partial_path + return controller.send(:controller_name), partial_path end end diff --git a/actionpack/test/controller/cookie_test.rb b/actionpack/test/controller/cookie_test.rb index 2b5b1cae9f..3f9dafacd6 100644 --- a/actionpack/test/controller/cookie_test.rb +++ b/actionpack/test/controller/cookie_test.rb @@ -28,6 +28,10 @@ class CookieTest < Test::Unit::TestCase render_text "hello world" end + def access_frozen_cookies + @cookies["wont"] = "work" + end + def rescue_action(e) raise end end @@ -63,6 +67,11 @@ class CookieTest < Test::Unit::TestCase assert_equal 2, process_request.headers["cookie"].size end + def test_setting_cookie_on_frozen_instance_variable + @request.action = "access_frozen_cookies" + assert_raises(TypeError) { process_request } + end + private def process_request TestController.process(@request, @response) diff --git a/actionpack/test/controller/helper_test.rb b/actionpack/test/controller/helper_test.rb index 0a9840f705..b824e40125 100644 --- a/actionpack/test/controller/helper_test.rb +++ b/actionpack/test/controller/helper_test.rb @@ -1,30 +1,20 @@ require File.dirname(__FILE__) + '/../abstract_unit' -$:.unshift(File.dirname(__FILE__) + '/../fixtures/helpers') -class TestController < ActionController::Base - attr_accessor :delegate_attr - def delegate_method() end - def rescue_action(e) raise end -end - -module Fun - class GamesController < ActionController::Base - def render_hello_world - render_template "hello: <%= stratego %>" - end +class HelperTest < Test::Unit::TestCase + HELPER_PATHS = %w(/../fixtures/helpers) + class TestController < ActionController::Base + attr_accessor :delegate_attr + def delegate_method() end def rescue_action(e) raise end end -end -module LocalAbcHelper - def a() end - def b() end - def c() end -end + module LocalAbcHelper + def a() end + def b() end + def c() end + end -class HelperTest < Test::Unit::TestCase - HELPER_PATHS = %w(/../fixtures/helpers) def setup # Increment symbol counter. @@ -112,13 +102,6 @@ class HelperTest < Test::Unit::TestCase assert template_methods.include?('delegate_attr=') end - def test_helper_for_nested_controller - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new - @request.action = "render_hello_world" - - assert_equal "hello: Iz guuut!", Fun::GamesController.process(@request, @response).body - end private def helper_methods; TestHelper.instance_methods end diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index afffd15793..f983960e2e 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -2,91 +2,86 @@ require File.dirname(__FILE__) + '/../abstract_unit' Customer = Struct.new("Customer", :name) -module Fun - class GamesController < ActionController::Base +class RenderTest < Test::Unit::TestCase + class TestController < ActionController::Base + layout :determine_layout + def hello_world end - end -end + def render_hello_world + render "test/hello_world" + end -class TestController < ActionController::Base - layout :determine_layout - - def hello_world - end + def render_hello_world_from_variable + @person = "david" + render_text "hello #{@person}" + end - def render_hello_world - render "test/hello_world" - end + def render_action_hello_world + render_action "hello_world" + end + + def render_text_hello_world + render_text "hello world" + end - def render_hello_world_from_variable - @person = "david" - render_text "hello #{@person}" - end + def render_custom_code + render_text "hello world", "404 Moved" + end + + def render_xml_hello + @name = "David" + render "test/hello" + end - def render_action_hello_world - render_action "hello_world" - end - - def render_text_hello_world - render_text "hello world" - end + def greeting + # let's just rely on the template + end - def render_custom_code - render_text "hello world", "404 Moved" - end - - def render_xml_hello - @name = "David" - render "test/hello" - end + def layout_test + render_action "hello_world" + end + + def builder_layout_test + render_action "hello" + end - def greeting - # let's just rely on the template - end + def partials_list + @customers = [ Customer.new("david"), Customer.new("mary") ] + render_action "list" + end - def layout_test - render_action "hello_world" - end - - def builder_layout_test - render_action "hello" - end + def modgreet + end - def partials_list - @customers = [ Customer.new("david"), Customer.new("mary") ] - render_action "list" + def rescue_action(e) raise end + + private + def determine_layout + case action_name + when "layout_test": "layouts/standard" + when "builder_layout_test": "layouts/builder" + end + end end - def rescue_action(e) raise end + TestController.template_root = File.dirname(__FILE__) + "/../fixtures/" + + class TestLayoutController < ActionController::Base + layout "layouts/standard" - private - def determine_layout - case action_name - when "layout_test": "layouts/standard" - when "builder_layout_test": "layouts/builder" - end + def hello_world + end + + def hello_world_outside_layout end -end - -TestController.template_root = File.dirname(__FILE__) + "/../fixtures/" - -class TestLayoutController < ActionController::Base - layout "layouts/standard" - - def hello_world - end - - def hello_world_outside_layout - end - def rescue_action(e) - raise unless ActionController::MissingTemplate === e + def rescue_action(e) + raise unless ActionController::MissingTemplate === e + end end -end -class RenderTest < Test::Unit::TestCase def setup @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new @@ -175,9 +170,10 @@ class RenderTest < Test::Unit::TestCase assert_equal "Hello: davidHello: mary", process_request.body end - def test_nested_rendering - @request.action = "hello_world" - assert_equal "Living in a nested world", Fun::GamesController.process(@request, @response).body + def test_module_rendering + @request.action = "modgreet" + @request.parameters["module"] = "scope" + assert_equal "<p>Beautiful modules!</p>", process_request.body end private diff --git a/actionpack/test/controller/request_test.rb b/actionpack/test/controller/request_test.rb index c31cdd460b..ebab660eab 100644 --- a/actionpack/test/controller/request_test.rb +++ b/actionpack/test/controller/request_test.rb @@ -31,28 +31,6 @@ class RequestTest < Test::Unit::TestCase @request.port = 8080 assert_equal ":8080", @request.port_string end - - def test_request_uri - @request.set_REQUEST_URI "http://www.rubyonrails.org/path/of/some/uri?mapped=1" - assert_equal "/path/of/some/uri?mapped=1", @request.request_uri - assert_equal "/path/of/some/uri", @request.path - - @request.set_REQUEST_URI "http://www.rubyonrails.org/path/of/some/uri" - assert_equal "/path/of/some/uri", @request.request_uri - assert_equal "/path/of/some/uri", @request.path - - @request.set_REQUEST_URI "/path/of/some/uri" - assert_equal "/path/of/some/uri", @request.request_uri - assert_equal "/path/of/some/uri", @request.path - - @request.set_REQUEST_URI "/" - assert_equal "/", @request.request_uri - assert_equal "/", @request.path - - @request.set_REQUEST_URI "/?m=b" - assert_equal "/?m=b", @request.request_uri - assert_equal "/", @request.path - end def test_host_with_port @request.env['HTTP_HOST'] = "rubyonrails.org:8080" diff --git a/actionpack/test/controller/routing_tests.rb b/actionpack/test/controller/routing_tests.rb deleted file mode 100644 index 307881554f..0000000000 --- a/actionpack/test/controller/routing_tests.rb +++ /dev/null @@ -1,401 +0,0 @@ -# Code Generated by ZenTest v. 2.3.0 -# Couldn't find class for name Routing -# classname: asrt / meth = ratio% -# ActionController::Routing::RouteSet: 0 / 16 = 0.00% -# ActionController::Routing::RailsRoute: 0 / 4 = 0.00% -# ActionController::Routing::Route: 0 / 8 = 0.00% - -RAILS_ROOT = "" -require File.dirname(__FILE__) + '/../abstract_unit' -require 'test/unit' -require 'cgi' - -class FakeController - attr_reader :controller_path - attr_reader :name - def initialize(name, controller_path) - @name = name - @controller_path = controller_path - end - def kind_of?(x) - x === Class || x == FakeController - end -end - -module Controllers - module Admin - UserController = FakeController.new 'Admin::UserController', 'admin/user' - AccessController = FakeController.new 'Admin::AccessController', 'admin/access' - end - module Editing - PageController = FakeController.new 'Editing::PageController', 'editing/page' - ImageController = FakeController.new 'Editing::ImageController', 'editing/image' - end - module User - NewsController = FakeController.new 'User::NewsController', 'user/news' - PaymentController = FakeController.new 'User::PaymentController', 'user/payment' - end - ContentController = FakeController.new 'ContentController', 'content' - ResourceController = FakeController.new 'ResourceController', 'resource' -end - -# Extend the modules with the required methods... -[Controllers, Controllers::Admin, Controllers::Editing, Controllers::User].each do |mod| - mod.instance_eval('alias :const_available? :const_defined?') - mod.constants.each {|k| Object.const_set(k, mod.const_get(k))} # export the modules & controller classes. -end - - -class RouteTests < Test::Unit::TestCase - def route(*args) - return @route if @route && (args.empty? || @args == args) - @args = args - @route = ActionController::Routing::Route.new(*args) - return @route - end - - def setup - self.route '/:controller/:action/:id' - @defaults = {:controller => 'content', :action => 'show', :id => '314'} - end - - # Don't put a leading / on the url. - # Make sure the controller is one from the above fake Controllers module. - def verify_recognize(url, expected_options, reason='') - url = url.split('/') if url.kind_of? String - reason = ": #{reason}" unless reason.empty? - controller_class, options = @route.recognize(url) - assert_not_equal nil, controller_class, "#{@route.inspect} didn't recognize #{url}#{reason}\n #{options}" - assert_equal expected_options, options, "#{@route.inspect} produced wrong options for #{url}#{reason}" - end - - # The expected url should not have a leading / - # You can use @defaults if you want a set of plausible defaults - def verify_generate(expected_url, expected_extras, options, defaults, reason='') - reason = "#{reason}: " unless reason.empty? - components, extras = @route.generate(options, defaults) - assert_not_equal nil, components, "#{reason}#{@route.inspect} didn't generate for \n options = #{options.inspect}\n defaults = #{defaults.inspect}\n #{extras}" - assert_equal expected_extras, extras, "#{reason} #{@route.inspect}.generate: incorrect extra's" - assert_equal expected_url, components.join('/'), "#{reason} #{@route.inspect}.generate: incorrect url" - end - - def test_recognize_default_unnested_with_action_and_id - verify_recognize('content/action/id', {:controller => 'content', :action => 'action', :id => 'id'}) - verify_recognize('content/show/10', {:controller => 'content', :action => 'show', :id => '10'}) - end - def test_generate_default_unnested_with_action_and_id_no_extras - verify_generate('content/action/id', {}, {:controller => 'content', :action => 'action', :id => 'id'}, @defaults) - verify_generate('content/show/10', {}, {:controller => 'content', :action => 'show', :id => '10'}, @defaults) - end - def test_generate_default_unnested_with_action_and_id - verify_generate('content/action/id', {:a => 'a'}, {:controller => 'content', :action => 'action', :id => 'id', :a => 'a'}, @defaults) - verify_generate('content/show/10', {:a => 'a'}, {:controller => 'content', :action => 'show', :id => '10', :a => 'a'}, @defaults) - end - - # Note that we can't put tests here for proper relative controller handline - # because that is handled by RouteSet. - def test_recognize_default_nested_with_action_and_id - verify_recognize('admin/user/action/id', {:controller => 'admin/user', :action => 'action', :id => 'id'}) - verify_recognize('admin/user/show/10', {:controller => 'admin/user', :action => 'show', :id => '10'}) - end - def test_generate_default_nested_with_action_and_id_no_extras - verify_generate('admin/user/action/id', {}, {:controller => 'admin/user', :action => 'action', :id => 'id'}, @defaults) - verify_generate('admin/user/show/10', {}, {:controller => 'admin/user', :action => 'show', :id => '10'}, @defaults) - end - def test_generate_default_nested_with_action_and_id_relative_to_root - verify_generate('admin/user/action/id', {:a => 'a'}, {:controller => 'admin/user', :action => 'action', :id => 'id', :a => 'a'}, @defaults) - verify_generate('admin/user/show/10', {:a => 'a'}, {:controller => 'admin/user', :action => 'show', :id => '10', :a => 'a'}, @defaults) - end - - def test_recognize_default_nested_with_action - verify_recognize('admin/user/action', {:controller => 'admin/user', :action => 'action'}) - verify_recognize('admin/user/show', {:controller => 'admin/user', :action => 'show'}) - end - def test_generate_default_nested_with_action_no_extras - verify_generate('admin/user/action', {}, {:controller => 'admin/user', :action => 'action'}, @defaults) - verify_generate('admin/user/show', {}, {:controller => 'admin/user', :action => 'show'}, @defaults) - end - def test_generate_default_nested_with_action - verify_generate('admin/user/action', {:a => 'a'}, {:controller => 'admin/user', :action => 'action', :a => 'a'}, @defaults) - verify_generate('admin/user/show', {:a => 'a'}, {:controller => 'admin/user', :action => 'show', :a => 'a'}, @defaults) - end - - def test_recognize_default_nested_with_id_and_index - verify_recognize('admin/user/index/hello', {:controller => 'admin/user', :id => 'hello', :action => 'index'}) - verify_recognize('admin/user/index/10', {:controller => 'admin/user', :id => "10", :action => 'index'}) - end - def test_generate_default_nested_with_id_no_extras - verify_generate('admin/user/index/hello', {}, {:controller => 'admin/user', :id => 'hello'}, @defaults) - verify_generate('admin/user/index/10', {}, {:controller => 'admin/user', :id => 10}, @defaults) - end - def test_generate_default_nested_with_id - verify_generate('admin/user/index/hello', {:a => 'a'}, {:controller => 'admin/user', :id => 'hello', :a => 'a'}, @defaults) - verify_generate('admin/user/index/10', {:a => 'a'}, {:controller => 'admin/user', :id => 10, :a => 'a'}, @defaults) - end - - def test_recognize_default_nested - verify_recognize('admin/user', {:controller => 'admin/user', :action => 'index'}) - verify_recognize('admin/user', {:controller => 'admin/user', :action => 'index'}) - end - def test_generate_default_nested_no_extras - verify_generate('admin/user/', {}, {:controller => 'admin/user'}, @defaults) - verify_generate('admin/user/', {}, {:controller => 'admin/user'}, @defaults) - end - def test_generate_default_nested - verify_generate('admin/user/', {:a => 'a'}, {:controller => 'admin/user', :a => 'a'}, @defaults) - verify_generate('admin/user/', {:a => 'a'}, {:controller => 'admin/user', :a => 'a'}, @defaults) - end - - # Test generate with a default controller set. - def test_generate_default_controller - route '/:controller/:action/:id', :action => 'index', :id => nil, :controller => 'content' - @defaults[:controller] = 'resource' - - verify_generate('', {}, {:controller => 'content'}, @defaults) - verify_generate('', {}, {:controller => 'content', :action => 'index'}, @defaults) - verify_generate('content/not-index', {}, {:controller => 'content', :action => 'not-index'}, @defaults) - verify_generate('content/index/10', {}, {:controller => 'content', :id => 10}, @defaults) - verify_generate('content/index/hi', {}, {:controller => 'content', :action => 'index', :id => 'hi'}, @defaults) - verify_generate('', {:a => 'a'}, {:controller => 'content', :a => 'a'}, @defaults) - verify_generate('', {:a => 'a'}, {:controller => 'content', :a => 'a'}, @defaults) - - # Call some other generator tests - test_generate_default_unnested_with_action_and_id - test_generate_default_nested_with_action_and_id_no_extras - test_generate_default_nested_with_id - test_generate_default_nested_with_id_no_extras - end - - # Test generate with a default controller set. - def test_generate_default_controller - route '/:controller/:action/:id', :action => 'index', :id => nil, :controller => 'content' - @defaults[:controller] = 'resource' - verify_recognize('', {:controller => 'content', :action => 'index'}) - verify_recognize('content', {:controller => 'content', :action => 'index'}) - verify_recognize('content/index', {:controller => 'content', :action => 'index'}) - verify_recognize('content/index/10', {:controller => 'content', :action => 'index', :id => '10'}) - end - # Make sure generation & recognition don't happen in some cases: - def test_no_generate_on_no_options - assert_equal nil, @route.generate({}, {})[0] - end - def test_requirements - route 'some_static/route', :controller => 'content' - assert_equal nil, @route.generate({}, {})[0] - assert_equal nil, @route.generate({:controller => "dog"}, {})[0] - assert_equal nil, @route.recognize([])[0] - assert_equal nil, @route.recognize(%w{some_static route with more than expected})[0] - end - - def test_basecamp - route 'clients/', :controller => 'content' - verify_generate('clients', {}, {:controller => 'content'}, {}) # Would like to have clients/ - verify_generate('clients', {}, {:controller => 'content'}, @defaults) - end - - def test_basecamp2 - route 'clients/:client_name/:project_name/', :controller => 'content', :action => 'start_page_redirect' - verify_recognize('clients/projects/2', {:controller => 'content', :client_name => 'projects', :project_name => '2', :action => 'start_page_redirect'}) - end - - def test_xal_style_dates - route 'articles/:category/:year/:month/:day', :controller => 'content', :action => 'list_articles', :category => 'all', :year => nil, :month => nil, :day =>nil - verify_recognize('articles', {:controller => 'content', :action => 'list_articles', :category => 'all'}) - verify_recognize('articles/porn', {:controller => 'content', :action => 'list_articles', :category => 'porn'}) - verify_recognize('articles/news/2005/08', {:controller => 'content', :action => 'list_articles', :category => 'news', :year => '2005', :month => '08'}) - verify_recognize('articles/news/2005/08/04', {:controller => 'content', :action => 'list_articles', :category => 'news', :year => '2005', :month => '08', :day => '04'}) - assert_equal nil, @route.recognize(%w{articles too many components are here})[0] - assert_equal nil, @route.recognize('')[0] - - verify_generate('articles', {}, {:controller => 'content', :action => 'list_articles'}, @defaults) - verify_generate('articles', {}, {:controller => 'content', :action => 'list_articles', :category => 'all'}, @defaults) - verify_generate('articles/news', {}, {:controller => 'content', :action => 'list_articles', :category => 'news'}, @defaults) - verify_generate('articles/news/2005', {}, {:controller => 'content', :action => 'list_articles', :category => 'news', :year => '2005'}, @defaults) - verify_generate('articles/news/2005/05', {}, {:controller => 'content', :action => 'list_articles', :category => 'news', :year => '2005', :month => '05'}, @defaults) - verify_generate('articles/news/2005/05/16', {}, {:controller => 'content', :action => 'list_articles', :category => 'news', :year => '2005', :month => '05', :day => '16'}, @defaults) - - assert_equal nil, @route.generate({:controller => 'content', :action => 'list_articles', :day => '2'}, @defaults)[0] - # The above case should fail because a nil value cannot be present in a path. - # In other words, since :day is given, :month and :year must be given too. - end - - - def test_no_controller - route 'some/:special/:route', :controller => 'a/missing/controller', :action => 'anything' - assert_raises(ActionController::RoutingError, "Should raise due to nonexistant controller") {@route.recognize(%w{some matching path})} - end - def test_bad_controller_path - assert_equal nil, @route.recognize(%w{no such controller fake_action id})[0] - end - def test_too_short_path - assert_equal nil, @route.recognize([])[0] - route 'some/static/route', :controller => 'content', :action => 'show' - assert_equal nil, route.recognize([])[0] - end - def test_too_long_path - assert_equal nil, @route.recognize(%w{content action id some extra components})[0] - end - def test_incorrect_static_component - route 'some/static/route', :controller => 'content', :action => 'show' - assert_equal nil, route.recognize(%w{an non_matching path})[0] - end - def test_no_controller_defined - route 'some/:path/:without/a/controller' - assert_equal nil, route.recognize(%w{some matching path a controller})[0] - end - - def test_mismatching_requirements - route 'some/path', :controller => 'content', :action => 'fish' - assert_equal nil, route.generate({:controller => 'admin/user', :action => 'list'})[0] - assert_equal nil, route.generate({:controller => 'content', :action => 'list'})[0] - assert_equal nil, route.generate({:controller => 'admin/user', :action => 'fish'})[0] - end - - def test_missing_value_for_generate - assert_equal nil, route.generate({})[0] # :controller is missing - end - def test_nils_inside_generated_path - route 'show/:year/:month/:day', :month => nil, :day => nil, :controller => 'content', :action => 'by_date' - assert_equal nil, route.generate({:year => 2005, :day => 10})[0] - end - - def test_expand_controller_path_non_nested_no_leftover - controller, leftovers = @route.send :eat_path_to_controller, %w{content} - assert_equal Controllers::ContentController, controller - assert_equal [], leftovers - end - def test_expand_controller_path_non_nested_with_leftover - controller, leftovers = @route.send :eat_path_to_controller, %w{content action id} - assert_equal Controllers::ContentController, controller - assert_equal %w{action id}, leftovers - end - def test_expand_controller_path_nested_no_leftover - controller, leftovers = @route.send :eat_path_to_controller, %w{admin user} - assert_equal Controllers::Admin::UserController, controller - assert_equal [], leftovers - end - def test_expand_controller_path_nested_no_leftover - controller, leftovers = @route.send :eat_path_to_controller, %w{admin user action id} - assert_equal Controllers::Admin::UserController, controller - assert_equal %w{action id}, leftovers - end -end - -class RouteSetTests < Test::Unit::TestCase - def setup - @set = ActionController::Routing::RouteSet.new - @rails_route = ActionController::Routing::Route.new '/:controller/:action/:id', :action => 'index', :id => nil - @request = ActionController::TestRequest.new({}, {}, nil) - end - def test_emptyness - assert_equal true, @set.empty?, "New RouteSets should respond to empty? with true." - @set.each { flunk "New RouteSets should be empty." } - end - def test_add_illegal_route - assert_raises(TypeError) {@set.add_route "I'm not actually a route."} - end - def test_add_normal_route - @set.add_route @rails_route - seen = false - @set.each do |route| - assert_equal @rails_route, route - flunk("Each should have yielded only a single route!") if seen - seen = true - end - end - - def test_expand_controller_path_non_relative - defaults = {:controller => 'admin/user', :action => 'list'} - options = {:controller => '/content'} - @set.expand_controller_path!(options, defaults) - assert_equal({:controller => 'content'}, options) - end - def test_expand_controller_path_relative_to_nested - defaults = {:controller => 'admin/user', :action => 'list'} - options = {:controller => 'access'} - @set.expand_controller_path!(options, defaults) - assert_equal({:controller => 'admin/access'}, options) - end - def test_expand_controller_path_relative_to_root - defaults = {:controller => 'content', :action => 'list'} - options = {:controller => 'resource'} - @set.expand_controller_path!(options, defaults) - assert_equal({:controller => 'resource'}, options) - end - def test_expand_controller_path_into_module - defaults = {:controller => 'content', :action => 'list'} - options = {:controller => 'admin/user'} - @set.expand_controller_path!(options, defaults) - assert_equal({:controller => 'admin/user'}, options) - end - def test_expand_controller_path_switch_module_with_absolute - defaults = {:controller => 'user/news', :action => 'list'} - options = {:controller => '/admin/user'} - @set.expand_controller_path!(options, defaults) - assert_equal({:controller => 'admin/user'}, options) - end - def test_expand_controller_no_default - options = {:controller => 'content'} - @set.expand_controller_path!(options, {}) - assert_equal({:controller => 'content'}, options) - end - - # Don't put a leading / on the url. - # Make sure the controller is one from the above fake Controllers module. - def verify_recognize(expected_controller, expected_path_parameters=nil, path=nil) - @set.add_route(@rails_route) if @set.empty? - @request.path = path if path - controller = @set.recognize!(@request) - assert_equal expected_controller, controller - assert_equal expected_path_parameters, @request.path_parameters if expected_path_parameters - end - - # The expected url should not have a leading / - # You can use @defaults if you want a set of plausible defaults - def verify_generate(expected_url, options, expected_extras={}) - @set.add_route(@rails_route) if @set.empty? - components, extras = @set.generate(options, @request) - assert_equal expected_extras, extras, "#incorrect extra's" - assert_equal expected_url, components.join('/'), "incorrect url" - end - def typical_request - @request.path_parameters = {:controller => 'content', :action => 'show', :id => '10'} - end - def typical_nested_request - @request.path_parameters = {:controller => 'admin/user', :action => 'grant', :id => '02seckar'} - end - - def test_generate_typical_controller_action_path - typical_request - verify_generate('content/list', {:controller => 'content', :action => 'list'}) - end - def test_generate_typical_controller_index_path_explicit_index - typical_request - verify_generate('content/', {:controller => 'content', :action => 'index'}) - end - def test_generate_typical_controller_index_path_explicit_index - typical_request - verify_generate('content/', {:controller => 'content', :action => 'index'}) - end - def test_generate_typical_controller_index_path_implicit_index - typical_request - @request.path_parameters[:controller] = 'resource' - verify_generate('content/', {:controller => 'content'}) - end - - def test_generate_no_perfect_route - typical_request - verify_generate('admin/user/show/43seckar', {:controller => 'admin/user', :action => 'show', :id => '43seckar', :likes_fishing => 'fuzzy(0.3)'}, {:likes_fishing => 'fuzzy(0.3)'}) - end - - def test_generate_no_match - @set.add_route(@rails_route) - @request.path_parameters = {} - assert_raises(ActionController::RoutingError) {@set.generate({}, @request)} - end - - - def test_encoded_strings - verify_recognize(Controllers::Admin::UserController, {:controller => 'admin/user', :action => 'info', :id => "Nicholas Seckar"}, path='/admin/user/info/Nicholas%20Seckar') - end -end diff --git a/actionpack/test/controller/url_obsolete.rb b/actionpack/test/controller/url_obsolete.rb deleted file mode 100644 index 4b6544dbf7..0000000000 --- a/actionpack/test/controller/url_obsolete.rb +++ /dev/null @@ -1,487 +0,0 @@ -require File.dirname(__FILE__) + '/../abstract_unit' -require 'action_controller/url_rewriter' - -MockRequest = Struct.new("MockRequest", :protocol, :host, :port, :path, :parameters, :path_parameters) -class MockRequest - def host_with_port - if (protocol == "http://" && port == 80) || (protocol == "https://" && port == 443) - host - else - host + ":#{port}" - end - end -end - -class UrlMockFactory - def self.create(path, parameters) - ActionController::UrlRewriter.new( - MockRequest.new("http://", "example.com", 80, path, parameters), - parameters - ) - end -end - -# old-style support for .new -module ActionController - class UrlRewriter - def self.old_new(request, controller, action) - request.parameters[:controller] = controller - request.parameters[:action] = action - return new(request, request.parameters) - end - end -end -class UrlTest < Test::Unit::TestCase - def setup - @library_url = ActionController::UrlRewriter.old_new(MockRequest.new( - "http://", - "www.singlefile.com", - 80, - "/library/books/ISBN/0743536703/show", - { "type" => "ISBN", "code" => "0743536703" } - ), "books", "show") - - @library_url_using_module = ActionController::UrlRewriter.old_new(MockRequest.new( - "http://", - "www.singlefile.com", - 80, - "/library/books/ISBN/0743536703/show", - { "type" => "ISBN", "code" => "0743536703", "module" => "library" } - ), "books", "show") - - @library_url_on_index = ActionController::UrlRewriter.old_new(MockRequest.new( - "http://", - "www.singlefile.com", - 80, - "/library/books/ISBN/0743536703/", - { "type" => "ISBN", "code" => "0743536703" } - ), "books", "index") - - @clean_urls = [ - ActionController::UrlRewriter.old_new(MockRequest.new( - "http://", "www.singlefile.com", 80, "/identity/", {} - ), "identity", "index"), - ActionController::UrlRewriter.old_new(MockRequest.new( - "http://", "www.singlefile.com", 80, "/identity", {} - ), "identity", "index") - ] - - @clean_url_with_id = ActionController::UrlRewriter.old_new(MockRequest.new( - "http://", "www.singlefile.com", 80, "/identity/show/5", { "id" => "5" } - ), "identity", "show") - - @clean_url_with_same_action_and_controller_name = ActionController::UrlRewriter.old_new(MockRequest.new( - "http://", "www.singlefile.com", 80, "/login/login", { } - ), "login", "login") - - @clean_url_with_same_action_and_controller_and_module_name = ActionController::UrlRewriter.old_new(MockRequest.new( - "http://", "www.singlefile.com", 80, "/login/login/login", { "module" => "login" } - ), "login", "login") - - @clean_url_with_id_as_char = ActionController::UrlRewriter.old_new(MockRequest.new( - "http://", "www.singlefile.com", 80, "/teachers/show/t", { "id" => "t" } - ), "teachers", "show") - end - - def test_clean_action - assert_equal "http://www.singlefile.com/library/books/ISBN/0743536703/edit", @library_url.rewrite(:action => "edit") - end - - def test_clean_action_to_another_host - assert_equal( - "http://www.booksphere.com/library/books/ISBN/0743536703/edit", - @library_url.rewrite(:action => "edit", :host => "www.booksphere.com") - ) - end - - def test_clean_action_to_another_host_and_protocol - assert_equal( - "https://www.booksphere.com/library/books/ISBN/0743536703/edit", - @library_url.rewrite(:action => "edit", :host => "www.booksphere.com", :protocol => "https://") - ) - end - - def test_clean_action_with_only_path - assert_equal "/library/books/ISBN/0743536703/edit", @library_url.rewrite(:action => "edit", :only_path => true) - end - - def test_action_from_index - assert_equal "http://www.singlefile.com/library/books/ISBN/0743536703/edit", @library_url_on_index.rewrite(:action => "edit") - end - - def test_action_from_index_on_clean - @clean_urls.each do |url| - assert_equal "http://www.singlefile.com/identity/edit", url.rewrite(:action => "edit") - end - end - - def test_action_without_prefix - assert_equal "http://www.singlefile.com/library/books/", @library_url.rewrite(:action => "index", :action_prefix => "") - end - - def test_action_with_prefix - assert_equal( - "http://www.singlefile.com/library/books/XTC/123/show", - @library_url.rewrite(:action => "show", :action_prefix => "XTC/123") - ) - end - - def test_action_prefix_alone - assert_equal( - "http://www.singlefile.com/library/books/XTC/123/", - @library_url.rewrite(:action_prefix => "XTC/123") - ) - end - - def test_action_with_suffix - assert_equal( - "http://www.singlefile.com/library/books/show/XTC/123", - @library_url.rewrite(:action => "show", :action_prefix => "", :action_suffix => "XTC/123") - ) - end - - def test_clean_controller - assert_equal "http://www.singlefile.com/library/settings/", @library_url.rewrite(:controller => "settings") - end - - def test_clean_controller_prefix - assert_equal "http://www.singlefile.com/shop/", @library_url.rewrite(:controller_prefix => "shop") - end - - def test_clean_controller_with_module - assert_equal "http://www.singlefile.com/shop/purchases/", @library_url.rewrite(:module => "shop", :controller => "purchases") - end - - def test_getting_out_of_a_module - assert_equal "http://www.singlefile.com/purchases/", @library_url_using_module.rewrite(:module => false, :controller => "purchases") - end - - def test_controller_and_action - assert_equal "http://www.singlefile.com/library/settings/show", @library_url.rewrite(:controller => "settings", :action => "show") - end - - def test_controller_and_action_and_anchor - assert_equal( - "http://www.singlefile.com/library/settings/show#5", - @library_url.rewrite(:controller => "settings", :action => "show", :anchor => "5") - ) - end - - def test_controller_and_action_and_empty_overwrite_params_and_anchor - assert_equal( - "http://www.singlefile.com/library/settings/show?code=0743536703&type=ISBN#5", - @library_url.rewrite(:controller => "settings", :action => "show", :overwrite_params => {}, :anchor => "5") - ) - end - - def test_controller_and_action_and_overwrite_params_and_anchor - assert_equal( - "http://www.singlefile.com/library/settings/show?code=0000001&type=ISBN#5", - @library_url.rewrite(:controller => "settings", :action => "show", :overwrite_params => {"code"=>"0000001"}, :anchor => "5") - ) - end - - def test_controller_and_action_and_overwrite_params_with_nil_value_and_anchor - assert_equal( - "http://www.singlefile.com/library/settings/show?type=ISBN#5", - @library_url.rewrite(:controller => "settings", :action => "show", :overwrite_params => {"code" => nil}, :anchor => "5") - ) - end - - def test_controller_and_action_params_and_overwrite_params_and_anchor - assert_equal( - "http://www.singlefile.com/library/settings/show?code=0000001&version=5.0#5", - @library_url.rewrite(:controller => "settings", :action => "show", :params=>{"version" => "5.0"}, :overwrite_params => {"code"=>"0000001"}, :anchor => "5") - ) - end - - def test_controller_and_action_and_params_anchor - assert_equal( - "http://www.singlefile.com/library/settings/show?update=1#5", - @library_url.rewrite(:controller => "settings", :action => "show", :params => { "update" => "1"}, :anchor => "5") - ) - end - - def test_controller_and_index_action - assert_equal "http://www.singlefile.com/library/settings/", @library_url.rewrite(:controller => "settings", :action => "index") - end - - def test_same_controller_and_action_names - assert_equal "http://www.singlefile.com/login/logout", @clean_url_with_same_action_and_controller_name.rewrite(:action => "logout") - end - - def xtest_same_module_and_controller_and_action_names - assert_equal "http://www.singlefile.com/login/login/logout", @clean_url_with_same_action_and_controller_and_module_name.rewrite(:action => "logout") - end - - def test_controller_and_action_with_same_name_as_controller - @clean_urls.each do |url| - assert_equal "http://www.singlefile.com/anything/identity", url.rewrite(:controller => "anything", :action => "identity") - end - end - - def test_controller_and_index_action_without_controller_prefix - assert_equal( - "http://www.singlefile.com/settings/", - @library_url.rewrite(:controller => "settings", :action => "index", :controller_prefix => "") - ) - end - - def test_controller_and_index_action_with_controller_prefix - assert_equal( - "http://www.singlefile.com/fantastic/settings/show", - @library_url.rewrite(:controller => "settings", :action => "show", :controller_prefix => "fantastic") - ) - end - - def test_path_parameters - assert_equal "http://www.singlefile.com/library/books/EXBC/0743536703/show", @library_url.rewrite(:path_params => {"type" => "EXBC"}) - end - - def test_parameters - assert_equal( - "http://www.singlefile.com/library/books/ISBN/0743536703/show?delete=1&name=David", - @library_url.rewrite(:params => {"delete" => "1", "name" => "David"}) - ) - end - - def test_parameters_with_id - @clean_urls.each do |url| - assert_equal( - "http://www.singlefile.com/identity/show?name=David&id=5", - url.rewrite( - :action => "show", - :params => { "id" => "5", "name" => "David" } - ) - ) - end - end - - def test_parameters_with_array - @clean_urls.each do |url| - assert_equal( - "http://www.singlefile.com/identity/show?id[]=3&id[]=5&id[]=10", - url.rewrite( - :action => "show", - :params => { 'id' => [ 3, 5, 10 ] } ) - ) - end - end - - def test_action_with_id - assert_equal( - "http://www.singlefile.com/identity/show/7", - @clean_url_with_id.rewrite( - :action => "show", - :id => 7 - ) - ) - @clean_urls.each do |url| - assert_equal( - "http://www.singlefile.com/identity/index/7", - url.rewrite(:id => 7) - ) - end - end - - def test_parameters_with_id_and_away - assert_equal( - "http://www.singlefile.com/identity/show/25?name=David", - @clean_url_with_id.rewrite( - :path_params => { "id" => "25" }, - :params => { "name" => "David" } - ) - ) - end - - def test_parameters_with_index_and_id - @clean_urls.each do |url| - assert_equal( - "http://www.singlefile.com/identity/index/25?name=David", - url.rewrite( - :path_params => { "id" => "25" }, - :params => { "name" => "David" } - ) - ) - end - end - - def test_action_going_away_from_id - assert_equal( - "http://www.singlefile.com/identity/list", - @clean_url_with_id.rewrite( - :action => "list" - ) - ) - end - - def test_parameters_with_direct_id_and_away - assert_equal( - "http://www.singlefile.com/identity/show/25?name=David", - @clean_url_with_id.rewrite( - :id => "25", - :params => { "name" => "David" } - ) - ) - end - - def test_parameters_with_direct_id_and_away - assert_equal( - "http://www.singlefile.com/store/open/25?name=David", - @clean_url_with_id.rewrite( - :controller => "store", - :action => "open", - :id => "25", - :params => { "name" => "David" } - ) - ) - end - - def test_parameters_to_id - @clean_urls.each do |url| - %w(show index).each do |action| - assert_equal( - "http://www.singlefile.com/identity/#{action}/25?name=David", - url.rewrite( - :action => action, - :path_params => { "id" => "25" }, - :params => { "name" => "David" } - ) - ) - end - end - end - - def test_parameters_from_id - assert_equal( - "http://www.singlefile.com/identity/", - @clean_url_with_id.rewrite( - :action => "index" - ) - ) - end - - def test_id_as_char_and_part_of_controller - assert_equal( - "http://www.singlefile.com/teachers/skill/5", - @clean_url_with_id_as_char.rewrite( - :action => "skill", - :id => 5 - ) - ) - end - - def test_from_clean_to_library - @clean_urls.each do |url| - assert_equal( - "http://www.singlefile.com/library/books/ISBN/0743536703/show?delete=1&name=David", - url.rewrite( - :controller_prefix => "library", - :controller => "books", - :action_prefix => "ISBN/0743536703", - :action => "show", - :params => { "delete" => "1", "name" => "David" } - ) - ) - end - end - - def test_from_library_to_clean - assert_equal( - "http://www.singlefile.com/identity/", - @library_url.rewrite( - :controller => "identity", :controller_prefix => "" - ) - ) - end - - def test_from_another_port - @library_url = ActionController::UrlRewriter.old_new(MockRequest.new( - "http://", - "www.singlefile.com", - 8080, - "/library/books/ISBN/0743536703/show", - { "type" => "ISBN", "code" => "0743536703" } - ), "books", "show") - - assert_equal( - "http://www.singlefile.com:8080/identity/", - @library_url.rewrite( - :controller => "identity", :controller_prefix => "" - ) - ) - end - - def test_basecamp - basecamp_url = ActionController::UrlRewriter.old_new(MockRequest.new( - "http://", - "projects.basecamp", - 80, - "/clients/disarray/1/msg/transcripts/", - {"category_name"=>"transcripts", "client_name"=>"disarray", "action"=>"index", "controller"=>"msg", "project_name"=>"1"} - ), "msg", "index") - - assert_equal( - "http://projects.basecamp/clients/disarray/1/msg/transcripts/1/comments", - basecamp_url.rewrite(:action_prefix => "transcripts/1", :action => "comments") - ) - end - - def test_on_explicit_index_page # My index page is very modest, thank you... - url = ActionController::UrlRewriter.old_new( - MockRequest.new( - "http://", "example.com", 80, "/controller/index", - {"controller"=>"controller", "action"=>"index"} - ), "controller", "index" - ) - assert_equal("http://example.com/controller/foo", url.rewrite(:action => 'foo')) - end - - def test_rewriting_on_similar_fragments - url = UrlMockFactory.create("/advertisements/advert/", {"controller"=>"advert", "action"=>"index"}) - assert_equal("http://example.com/advertisements/advert/news", url.rewrite(:action => 'news')) - end - - def test_rewriting_on_similar_fragments_with_action_prefixes - url = UrlMockFactory.create( - "/clients/prall/1/msg/all/", - { "category_name"=>"all", "client_name"=>"prall", "action"=>"index", "controller"=>"msg", "project_name"=>"1"} - ) - - assert_equal( - "http://example.com/clients/prall/1/msg/all/new", - url.rewrite({ :controller => "msg", :action_prefix => "all", :action => "new" }) - ) - - url = UrlMockFactory.create( - "/clients/prall/1/msg/all/", - { "category_name"=>"all", "client_name"=>"prall", "action"=>"index", "controller"=>"msg", "project_name"=>"1"} - ) - - assert_equal( - "http://example.com/clients/prall/1/msg/allous/new", - url.rewrite({ :controller => "msg", :action_prefix => "allous", :action => "new" }) - ) - end - - def test_clean_application_prefix - assert_equal "http://www.singlefile.com/namespace/library/books/ISBN/0743536703/show", - @library_url.rewrite(:application_prefix => "/namespace") - end - - def test_clean_application_prefix_with_controller_prefix - assert_equal "http://www.singlefile.com/namespace/shop/", - @library_url.rewrite(:application_prefix => "/namespace", - :controller_prefix => "shop" ) - end - - def test_blank_application_prefix - assert_equal "http://www.singlefile.com/library/books/ISBN/0743536703/show", - @library_url.rewrite(:application_prefix => "") - end - - def test_nil_application_prefix - assert_equal "http://www.singlefile.com/library/books/ISBN/0743536703/show", - @library_url.rewrite(:application_prefix => nil) - end -end diff --git a/actionpack/test/fixtures/fun/games/hello_world.rhtml b/actionpack/test/fixtures/fun/games/hello_world.rhtml deleted file mode 100644 index 1ebfbe2539..0000000000 --- a/actionpack/test/fixtures/fun/games/hello_world.rhtml +++ /dev/null @@ -1 +0,0 @@ -Living in a nested world
\ No newline at end of file diff --git a/actionpack/test/fixtures/helpers/fun/games_helper.rb b/actionpack/test/fixtures/helpers/fun/games_helper.rb deleted file mode 100644 index bf60d9db0c..0000000000 --- a/actionpack/test/fixtures/helpers/fun/games_helper.rb +++ /dev/null @@ -1,3 +0,0 @@ -module Fun::GamesHelper - def stratego() "Iz guuut!" end -end
\ No newline at end of file diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index cf9fc0a728..7a005ce970 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -2,10 +2,6 @@ * Added IndifferentAccess as a way to wrap a hash by a symbol-based store that also can be accessed by string keys -* Added Inflector.constantize to turn "Admin::User" into a reference for the constant Admin::User - -* Added that Inflector.camelize and Inflector.underscore can deal with modules like turning "Admin::User" into "admin/user" and back - * Added Inflector.humanize to turn attribute names like employee_salary into "Employee salary". Used by automated error reporting in AR. * Added availability of class inheritable attributes to the masses #477 [bitsweat] diff --git a/activesupport/lib/core_ext/hash/indifferent_access.rb b/activesupport/lib/core_ext/hash/indifferent_access.rb index 2353cfaf3b..3fe0999866 100644 --- a/activesupport/lib/core_ext/hash/indifferent_access.rb +++ b/activesupport/lib/core_ext/hash/indifferent_access.rb @@ -8,17 +8,17 @@ class HashWithIndifferentAccess < Hash end end - alias_method :regular_reader, :[] unless method_defined?(:regular_reader) + alias_method :regular_read, :[] def [](key) case key - when Symbol: regular_reader(key) || regular_reader(key.to_s) - when String: regular_reader(key) || regular_reader(key.to_sym) - else regular_reader(key) + when Symbol: regular_read(key) || regular_read(key.to_s) + when String: regular_read(key) || regular_read(key.to_sym) + else regular_read(key) end end - alias_method :regular_writer, :[]= unless method_defined?(:regular_writer) + alias_method :regular_writer, :[]= def []=(key, value) regular_writer(key.is_a?(String) ? key.to_sym : key, value) diff --git a/activesupport/lib/core_ext/string/inflections.rb b/activesupport/lib/core_ext/string/inflections.rb index aa4ff3a74d..5d1070b00a 100644 --- a/activesupport/lib/core_ext/string/inflections.rb +++ b/activesupport/lib/core_ext/string/inflections.rb @@ -39,10 +39,6 @@ module ActiveSupport #:nodoc: def foreign_key(separate_class_name_and_id_with_underscore = true) Inflector.foreign_key(self, separate_class_name_and_id_with_underscore) end - - def constantize - Inflector.constantize(self) - end end end end diff --git a/activesupport/lib/dependencies.rb b/activesupport/lib/dependencies.rb index 0a9b8e1d3d..7f53998e7a 100644 --- a/activesupport/lib/dependencies.rb +++ b/activesupport/lib/dependencies.rb @@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/module_attribute_accessors' module Dependencies extend self - + @@loaded = [ ] mattr_accessor :loaded @@ -41,68 +41,6 @@ module Dependencies def remove_subclasses_for(*classes) classes.each { |klass| klass.remove_subclasses } end - - # LoadingModules implement namespace-safe dynamic loading. - # They support automatic loading via const_missing, allowing contained items to be automatically - # loaded when required. No extra syntax is required, as expressions such as Controller::Admin::UserController - # load the relavent files automatically. - # - # Ruby-style modules are supported, as a folder named 'submodule' will load 'submodule.rb' when available. - class LoadingModule < Module - attr_reader :path - - def initialize(filesystem_root, path=[]) - @path = path - @filesystem_root = filesystem_root - end - - # The path to this module in the filesystem. - # Any subpath provided is taken to be composed of filesystem names. - def filesystem_path(subpath=[]) - File.join(@filesystem_root, self.path, subpath) - end - - # Load missing constants if possible. - def const_missing(name) - return const_get(name) if const_defined?(name) == false && const_load!(name) - super(name) - end - - # Load the controller class or a parent module. - def const_load!(name) - name = name.to_s if name.kind_of? Symbol - - if File.directory? filesystem_path(name.underscore) - # Is it a submodule? If so, create a new LoadingModule *before* loading it. - # This ensures that subitems will be loadable - new_module = LoadingModule.new(@filesystem_root, self.path + [name.underscore]) - const_set(name, new_module) - Object.const_set(name, new_module) if @path.empty? - end - - source_file = filesystem_path("#{(name == 'ApplicationController' ? 'Application' : name).underscore}.rb") - self.load_file(source_file) if File.file?(source_file) - self.const_defined?(name.camelize) - end - - # Is this name present or loadable? - # This method is used by Routes to find valid controllers. - def const_available?(name) - name = name.to_s unless name.kind_of? String - File.directory?(filesystem_path(name.underscore)) || File.file?(filesystem_path("#{name.underscore}.rb")) - end - - def clear - constants.each do |name| - Object.send(:remove_const, name) if Object.const_defined?(name) && @path.empty? - self.send(:remove_const, name) - end - end - - def load_file(file_path) - Controllers.module_eval(IO.read(file_path), file_path, 1) # Hard coded Controller line here!!! - end - end end Object.send(:define_method, :require_or_load) { |file_name| Dependencies.require_or_load(file_name) } unless Object.respond_to?(:require_or_load) @@ -114,9 +52,6 @@ class Object #:nodoc: # Use const_missing to autoload associations so we don't have to # require_association when using single-table inheritance. def const_missing(class_id) - if Object.const_defined?(:Controllers) and Object::Controllers.const_available?(class_id) - return Object::Controllers.const_get(class_id) - end begin require_or_load(class_id.to_s.demodulize.underscore) if Object.const_defined?(class_id) then return Object.const_get(class_id) else raise LoadError end diff --git a/activesupport/lib/inflector.rb b/activesupport/lib/inflector.rb index a9b2f87be4..065fad3762 100644 --- a/activesupport/lib/inflector.rb +++ b/activesupport/lib/inflector.rb @@ -20,11 +20,11 @@ module Inflector end def camelize(lower_case_and_underscored_word) - lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase } + lower_case_and_underscored_word.to_s.gsub(/(^|_)(.)/){$2.upcase} end def underscore(camel_cased_word) - camel_cased_word.to_s.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z])/,'\1_\2').gsub(/([a-z])([A-Z])/,'\1_\2').downcase + camel_cased_word.to_s.gsub(/([A-Z]+)([A-Z])/,'\1_\2').gsub(/([a-z])([A-Z])/,'\1_\2').downcase end def humanize(lower_case_and_underscored_word) @@ -47,13 +47,7 @@ module Inflector Inflector.underscore(Inflector.demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id") end - - def constantize(camel_cased_word) - camel_cased_word.split("::").inject(Object) do |final_type, part| - final_type = final_type.const_get(part) - end - end - + private def plural_rules #:doc: [ diff --git a/activesupport/test/inflector_test.rb b/activesupport/test/inflector_test.rb index cdab0f9ed0..4523430ebe 100644 --- a/activesupport/test/inflector_test.rb +++ b/activesupport/test/inflector_test.rb @@ -1,13 +1,6 @@ require 'test/unit' require File.dirname(__FILE__) + '/../lib/inflector' -module A - module B - class C - end - end -end - class InflectorTest < Test::Unit::TestCase SingularToPlural = { "search" => "searches", @@ -57,12 +50,6 @@ class InflectorTest < Test::Unit::TestCase "SpecialGuest" => "special_guest", "ApplicationController" => "application_controller" } - - CamelWithModuleToUnderscoreWithSlash = { - "Admin::Product" => "admin/product", - "Users::Commission::Department" => "users/commission/department", - "UsersSection::CommissionDepartment" => "users_section/commission_department", - } ClassNameToForeignKeyWithUnderscore = { "Person" => "person_id", @@ -113,18 +100,6 @@ class InflectorTest < Test::Unit::TestCase assert_equal "html_tidy_generator", Inflector.underscore("HTMLTidyGenerator") end - def test_camelize_with_module - CamelWithModuleToUnderscoreWithSlash.each do |camel, underscore| - assert_equal(camel, Inflector.camelize(underscore)) - end - end - - def test_underscore_with_slashes - CamelWithModuleToUnderscoreWithSlash.each do |camel, underscore| - assert_equal(underscore, Inflector.underscore(camel)) - end - end - def test_demodulize assert_equal "Account", Inflector.demodulize("MyApplication::Billing::Account") end @@ -156,10 +131,4 @@ class InflectorTest < Test::Unit::TestCase assert_equal(human, Inflector.humanize(underscore)) end end - - def test_constantize - assert_equal A::B::C, Inflector.constantize("A::B::C") - assert_equal InflectorTest, Inflector.constantize("InflectorTest") - assert_raises(NameError) { Inflector.constantize("UnknownClass") } - end end
\ No newline at end of file diff --git a/activesupport/test/loading_module/admin/access_controller.rb b/activesupport/test/loading_module/admin/access_controller.rb deleted file mode 100644 index ddcbda8132..0000000000 --- a/activesupport/test/loading_module/admin/access_controller.rb +++ /dev/null @@ -1,2 +0,0 @@ -class Admin::AccessController -end diff --git a/activesupport/test/loading_module/admin/user_controller.rb b/activesupport/test/loading_module/admin/user_controller.rb deleted file mode 100644 index f265f1597a..0000000000 --- a/activesupport/test/loading_module/admin/user_controller.rb +++ /dev/null @@ -1,2 +0,0 @@ -class Admin::UserController -end diff --git a/activesupport/test/loading_module/content_controller.rb b/activesupport/test/loading_module/content_controller.rb deleted file mode 100644 index f0870161e5..0000000000 --- a/activesupport/test/loading_module/content_controller.rb +++ /dev/null @@ -1,2 +0,0 @@ -class ContentController -end diff --git a/activesupport/test/loading_module/resource_controller.rb b/activesupport/test/loading_module/resource_controller.rb deleted file mode 100644 index d948f366bf..0000000000 --- a/activesupport/test/loading_module/resource_controller.rb +++ /dev/null @@ -1,2 +0,0 @@ -class ResourceController -end diff --git a/activesupport/test/loading_module_tests.rb b/activesupport/test/loading_module_tests.rb deleted file mode 100644 index c1d8c7de62..0000000000 --- a/activesupport/test/loading_module_tests.rb +++ /dev/null @@ -1,63 +0,0 @@ -require 'test/unit' -require '../lib/core_ext.rb' -require '../lib/dependencies.rb' - -STAGING_DIRECTORY = 'loading_module' - -class LoadingModuleTests < Test::Unit::TestCase - def setup - @loading_module = Dependencies::LoadingModule.new(STAGING_DIRECTORY) - Object.const_set(:Controllers, @loading_module) - end - def teardown - @loading_module.clear - Object.send :remove_const, :Controllers - end - - def test_setup - assert_kind_of Dependencies::LoadingModule, @loading_module - end - - def test_const_available - assert @loading_module.const_available?(:Admin) - assert @loading_module.const_available?(:ResourceController) - assert @loading_module.const_available?(:ContentController) - assert @loading_module.const_available?("ContentController") - - assert_equal false, @loading_module.const_available?(:AdminController) - assert_equal false, @loading_module.const_available?(:RandomName) - end - - def test_const_load_module - assert @loading_module.const_load!(:Admin) - assert_kind_of Module, @loading_module::Admin - assert_kind_of Dependencies::LoadingModule, @loading_module::Admin - end - - def test_const_load_controller - assert @loading_module.const_load!(:ContentController) - assert_kind_of Class, @loading_module::ContentController - end - - def test_const_load_nested_controller - assert @loading_module.const_load!(:Admin) - assert @loading_module::Admin.const_available?(:UserController) - assert @loading_module::Admin.const_load!(:UserController) - assert_kind_of Class, @loading_module::Admin::UserController - end - - def test_pretty_access - assert_kind_of Module, @loading_module::Admin - assert_kind_of Dependencies::LoadingModule, @loading_module::Admin - - assert_kind_of Class, @loading_module::Admin::UserController - assert_kind_of Class, @loading_module::Admin::AccessController - assert_kind_of Class, @loading_module::ResourceController - assert_kind_of Class, @loading_module::ContentController - end - - def test_missing_name - assert_raises(NameError) {@loading_module::PersonController} - assert_raises(NameError) {@loading_module::Admin::FishController} - end -end
\ No newline at end of file diff --git a/railties/bin/destroy b/railties/bin/destroy index ba6dc7703f..6c1848ce1e 100644 --- a/railties/bin/destroy +++ b/railties/bin/destroy @@ -1,5 +1,8 @@ #!/usr/local/bin/ruby require File.dirname(__FILE__) + '/../config/environment' require 'rails_generator' +require 'rails_generator/simple_logger' require 'rails_generator/scripts/destroy' + +Rails::Generator::Base.logger = Rails::Generator::SimpleLogger.new(STDOUT) Rails::Generator::Scripts::Destroy.new.run(ARGV) diff --git a/railties/bin/generate b/railties/bin/generate index dde69e61a1..8bce002510 100755 --- a/railties/bin/generate +++ b/railties/bin/generate @@ -1,5 +1,8 @@ #!/usr/local/bin/ruby require File.dirname(__FILE__) + '/../config/environment' require 'rails_generator' +require 'rails_generator/simple_logger' require 'rails_generator/scripts/generate' + +Rails::Generator::Base.logger = Rails::Generator::SimpleLogger.new(STDOUT) Rails::Generator::Scripts::Generate.new.run(ARGV) diff --git a/railties/bin/rails b/railties/bin/rails index 3d23b99609..da9b2af041 100755 --- a/railties/bin/rails +++ b/railties/bin/rails @@ -1,4 +1,7 @@ require File.dirname(__FILE__) + '/../lib/rails_generator' +require 'rails_generator/simple_logger' require 'rails_generator/scripts/generate' + +Rails::Generator::Base.logger = Rails::Generator::SimpleLogger.new(STDOUT) Rails::Generator::Base.use_application_sources! Rails::Generator::Scripts::Generate.new.run(ARGV, :generator => 'app') diff --git a/railties/bin/update b/railties/bin/update index 430d325b07..64cc49cf02 100644 --- a/railties/bin/update +++ b/railties/bin/update @@ -1,5 +1,8 @@ #!/usr/local/bin/ruby require File.dirname(__FILE__) + '/../config/environment' require 'rails_generator' +require 'rails_generator/simple_logger' require 'rails_generator/scripts/update' + +Rails::Generator::Base.logger = Rails::Generator::SimpleLogger.new(STDOUT) Rails::Generator::Scripts::Update.new.run(ARGV) diff --git a/railties/configs/apache.conf b/railties/configs/apache.conf index 1aa874c866..5548292f8d 100755 --- a/railties/configs/apache.conf +++ b/railties/configs/apache.conf @@ -1,6 +1,61 @@ +# General Apache options +AddHandler fastcgi-script .fcgi +AddHandler cgi-script .cgi +Options +FollowSymLinks +ExecCGI + +# Make sure that mod_ruby.c has been added and loaded as a module with Apache RewriteEngine On -RewriteCond %{REQUEST_FILENAME} !-f -RewriteRule ^(.*)$ /dispatch.fcgi?$1 [QSA,L] +# Change extension from .cgi to .fcgi to switch to FCGI and to .rb to switch to mod_ruby +RewriteBase /dispatch.cgi + +# Enable this rewrite rule to point to the controller/action that should serve root. +# RewriteRule ^$ /controller/action [R] + +# <caching> +# no query string? +RewriteCond %{QUERY_STRING} ^$ + +# no POST method? +RewriteCond %{REQUEST_METHOD} !^POST$ [NC] + +# Request filename is a directory? +RewriteCond %{REQUEST_FILENAME} -d + +# Request filename + '/index' is a file? +RewriteCond %{REQUEST_FILENAME}/index -f + +# Rewrite to request filename + '/index' and finish +RewriteRule ^(.*)/?$ $1/index [QSA,L] + +# no query string? +RewriteCond %{QUERY_STRING} ^$ + +# no POST method? +RewriteCond %{REQUEST_METHOD} !^POST$ [NC] + +# Request filename is a file? +RewriteCond %{REQUEST_FILENAME} -f + +# Finish rewriting +RewriteRule .* - [L] + +# Set default type of cached files to text/html +DefaultType text/html +# </caching> + +# Add missing slash +RewriteRule ^([-_a-zA-Z0-9]+)$ /$1/ [R] + +# Default rewriting rules. +RewriteRule ^([-_a-zA-Z0-9]+)/([-_a-zA-Z0-9]+)/([0-9]+)$ ?controller=$1&action=$2&id=$3 [QSA,L] +RewriteRule ^([-_a-zA-Z0-9]+)/([-_a-zA-Z0-9]+)$ ?controller=$1&action=$2 [QSA,L] +RewriteRule ^([-_a-zA-Z0-9]+)/$ ?controller=$1&action=index [QSA,L] + +RewriteRule ^([-_a-zA-Z0-9]+)/([-_a-zA-Z0-9]+)/([-_a-zA-Z0-9]+)/([0-9]+)$ ?module=$1&controller=$2&action=$3&id=$4 [QSA,L] +RewriteRule ^([-_a-zA-Z0-9]+)/([-_a-zA-Z0-9]+)/([-_a-zA-Z0-9]+)$ ?module=$1&controller=$2&action=$3 [QSA,L] +RewriteRule ^([-_a-zA-Z0-9]+)/([-_a-zA-Z0-9]+)/$ ?module=$1&controller=$2&action=index [QSA,L] + +# You can also point these error messages to a controller/action ErrorDocument 500 /500.html ErrorDocument 404 /404.html
\ No newline at end of file diff --git a/railties/environments/shared.rb b/railties/environments/shared.rb index f8a8e8cb6f..8e36ae6670 100644 --- a/railties/environments/shared.rb +++ b/railties/environments/shared.rb @@ -39,8 +39,6 @@ require_dependency "environments/#{RAILS_ENV}" ActiveRecord::Base.configurations = YAML::load(File.open("#{RAILS_ROOT}/config/database.yml")) ActiveRecord::Base.establish_connection -Controllers = Dependencies::LoadingModule.new(File.expand_path(File.join(RAILS_ROOT, 'app', 'controllers'))) - # Configure defaults if the included environment did not. begin diff --git a/railties/environments/shared_for_gem.rb b/railties/environments/shared_for_gem.rb index 948b5e47eb..a277641a99 100644 --- a/railties/environments/shared_for_gem.rb +++ b/railties/environments/shared_for_gem.rb @@ -36,8 +36,6 @@ require_dependency "environments/#{RAILS_ENV}" ActiveRecord::Base.configurations = YAML::load(File.open("#{RAILS_ROOT}/config/database.yml")) ActiveRecord::Base.establish_connection -Controllers = Dependencies::LoadingModule.new(File.expand_path(File.join(RAILS_ROOT, 'app', 'controllers'))) - # Configure defaults if the included environment did not. begin diff --git a/railties/generators/model/USAGE b/railties/generators/model/USAGE new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/railties/generators/model/USAGE diff --git a/railties/lib/dispatcher.rb b/railties/lib/dispatcher.rb index 74de93713c..566b031295 100644 --- a/railties/lib/dispatcher.rb +++ b/railties/lib/dispatcher.rb @@ -24,34 +24,56 @@ require 'breakpoint' class Dispatcher - class << self + class <<self def dispatch(cgi = CGI.new, session_options = ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS) begin - prepare_application - request, response = ActionController::CgiRequest.new(cgi, session_options), ActionController::CgiResponse.new(cgi) - ActionController::Routing::Routes.recognize!(request).process(request, response).out + Breakpoint.activate_drb("druby://localhost:#{BREAKPOINT_SERVER_PORT}", nil, !defined?(FastCGI)) if defined?(BREAKPOINT_SERVER_PORT) + + request = ActionController::CgiRequest.new(cgi, session_options) + response = ActionController::CgiResponse.new(cgi) + + controller_name, module_name = controller_name(request.parameters), module_name(request.parameters) + + require_or_load("application") + require_or_load(controller_path(controller_name, module_name)) + + controller_class(controller_name).process(request, response).out rescue Object => exception ActionController::Base.process_with_exception(request, response, exception).out ensure - reset_application + reset_application if Dependencies.load? + Breakpoint.deactivate_drb if defined?(BREAKPOINT_SERVER_PORT) end end private - def prepare_application - ActionController::Routing::Routes.reload if Dependencies.load? - Breakpoint.activate_drb("druby://localhost:#{BREAKPOINT_SERVER_PORT}", nil, !defined?(FastCGI)) if defined?(BREAKPOINT_SERVER_PORT) - Controllers.const_load!("application") unless Controllers.const_defined?(:ApplicationController) + def reset_application + Dependencies.clear + Dependencies.remove_subclasses_for(ActiveRecord::Base, ActiveRecord::Observer, ActionController::Base) end - def reset_application - if Dependencies.load? - Controllers.clear - Dependencies.clear - Dependencies.remove_subclasses_for(ActiveRecord::Base, ActiveRecord::Observer, ActionController::Base) + def controller_path(controller_name, module_name = nil) + if module_name + "#{module_name}/#{controller_name.underscore}_controller" + else + "#{controller_name.underscore}_controller" end + end - Breakpoint.deactivate_drb if defined?(BREAKPOINT_SERVER_PORT) + def controller_class(controller_name) + Object.const_get(controller_class_name(controller_name)) + end + + def controller_class_name(controller_name) + "#{controller_name.camelize}Controller" + end + + def controller_name(parameters) + parameters["controller"].downcase.gsub(/[^_a-zA-Z0-9]/, "").untaint + end + + def module_name(parameters) + parameters["module"].downcase.gsub(/[^_a-zA-Z0-9]/, "").untaint if parameters["module"] end end end
\ No newline at end of file diff --git a/railties/lib/rails_generator.rb b/railties/lib/rails_generator.rb index c46989819d..0875a22dee 100644 --- a/railties/lib/rails_generator.rb +++ b/railties/lib/rails_generator.rb @@ -23,7 +23,7 @@ $:.unshift(File.dirname(__FILE__)) -require 'rails_generator/support/core_ext' +require 'support/core_ext' require 'rails_generator/base' require 'rails_generator/lookup' @@ -31,7 +31,3 @@ require 'rails_generator/commands' Rails::Generator::Base.send(:include, Rails::Generator::Lookup) Rails::Generator::Base.send(:include, Rails::Generator::Commands) - -# Set up a default logger for convenience. -require 'rails_generator/simple_logger' -Rails::Generator::Base.logger = Rails::Generator::SimpleLogger.new(STDOUT) diff --git a/railties/lib/rails_generator/base.rb b/railties/lib/rails_generator/base.rb index 92a54e2453..065ce63966 100644 --- a/railties/lib/rails_generator/base.rb +++ b/railties/lib/rails_generator/base.rb @@ -1,5 +1,5 @@ -require File.dirname(__FILE__) + '/support/class_attribute_accessors' -require File.dirname(__FILE__) + '/support/inflector' +require File.dirname(__FILE__) + '/../support/class_attribute_accessors' +require File.dirname(__FILE__) + '/../support/inflector' require File.dirname(__FILE__) + '/options' require File.dirname(__FILE__) + '/manifest' require File.dirname(__FILE__) + '/spec' @@ -69,8 +69,8 @@ module Rails @source_root = options[:source] || File.join(spec.path, 'templates') if options[:destination] @destination_root = options[:destination] - elsif defined? ::RAILS_ROOT - @destination_root = ::RAILS_ROOT + elsif Object.const_defined?(:RAILS_ROOT) + @destination_root = Object.const_get(:RAILS_ROOT) end # Silence the logger if requested. @@ -173,20 +173,11 @@ module Rails def assign_names!(name) @name = name base_name, @class_path, @class_nesting = extract_modules(@name) - @class_name_without_nesting, @singular_name, @plural_name = inflect_names(base_name) - if @class_nesting.empty? - @class_name = @class_name_without_nesting - else - @class_name = "#{@class_nesting}::#{@class_name_without_nesting}" - end + @class_name, @singular_name, @plural_name = inflect_names(base_name) end - # Extract modules from filesystem-style or ruby-style path: - # good/fun/stuff - # Good::Fun::Stuff - # produce the same results. def extract_modules(name) - modules = name.include?('/') ? name.split('/') : name.split('::') + modules = name.split('/') name = modules.pop path = modules.map { |m| m.underscore } nesting = modules.map { |m| m.camelize }.join('::') diff --git a/railties/lib/rails_generator/generators/applications/app/app_generator.rb b/railties/lib/rails_generator/generators/applications/app/app_generator.rb index 4a04757ddd..0beb11b237 100644 --- a/railties/lib/rails_generator/generators/applications/app/app_generator.rb +++ b/railties/lib/rails_generator/generators/applications/app/app_generator.rb @@ -1,16 +1,15 @@ -require 'rbconfig' - class AppGenerator < Rails::Generator::Base DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name']) default_options :gem => true, :shebang => DEFAULT_SHEBANG - mandatory_options :source => "#{File.dirname(__FILE__)}/../../../../.." + mandatory_options :source => "#{File.dirname(__FILE__)}/../.." def initialize(runtime_args, runtime_options = {}) super usage if args.empty? @destination_root = args.shift + puts "eek! #{destination_root.inspect}" end def manifest @@ -33,7 +32,6 @@ class AppGenerator < Rails::Generator::Base # database.yml and .htaccess m.template "configs/database.yml", "config/database.yml" - m.template "configs/routes.rb", "config/routes.rb" m.template "configs/apache.conf", "public/.htaccess" # Environments diff --git a/railties/lib/rails_generator/generators/components/controller/controller_generator.rb b/railties/lib/rails_generator/generators/components/controller/controller_generator.rb index d537031fea..1f7e69d124 100644 --- a/railties/lib/rails_generator/generators/components/controller/controller_generator.rb +++ b/railties/lib/rails_generator/generators/components/controller/controller_generator.rb @@ -4,11 +4,8 @@ class ControllerGenerator < Rails::Generator::NamedBase # Check for class naming collisions. m.class_collisions "#{class_name}Controller", "#{class_name}ControllerTest", "#{class_name}Helper" - # Controller, helper, views, and test directories. - m.directory File.join('app/controllers', class_path) - m.directory File.join('app/helpers', class_path) + # Views directory even if there are no actions. m.directory File.join('app/views', class_path, file_name) - m.directory File.join('test/functional', class_path) # Controller class, functional test, and helper class. m.template 'controller.rb', diff --git a/railties/lib/rails_generator/generators/components/controller/templates/functional_test.rb b/railties/lib/rails_generator/generators/components/controller/templates/functional_test.rb index 76e2b33ba5..c975cb3ce3 100644 --- a/railties/lib/rails_generator/generators/components/controller/templates/functional_test.rb +++ b/railties/lib/rails_generator/generators/components/controller/templates/functional_test.rb @@ -7,8 +7,7 @@ class <%= class_name %>Controller; def rescue_action(e) raise e end; end class <%= class_name %>ControllerTest < Test::Unit::TestCase def setup @controller = <%= class_name %>Controller.new - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new + @request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new end # Replace this with your real tests. diff --git a/railties/lib/rails_generator/generators/components/mailer/mailer_generator.rb b/railties/lib/rails_generator/generators/components/mailer/mailer_generator.rb index d8ddb43644..81d4599f7f 100644 --- a/railties/lib/rails_generator/generators/components/mailer/mailer_generator.rb +++ b/railties/lib/rails_generator/generators/components/mailer/mailer_generator.rb @@ -4,28 +4,21 @@ class MailerGenerator < Rails::Generator::NamedBase # Check for class naming collisions. m.class_collisions class_name, "#{class_name}Test" - # Mailer, view, test, and fixture directories. - m.directory File.join('app/models', class_path) - m.directory File.join('app/views', class_path, file_name) - m.directory File.join('test/unit', class_path) - m.directory File.join('test/fixtures', class_path, table_name) - # Mailer class and unit test. - m.template "mailer.rb", File.join('app/models', - class_path, - "#{file_name}.rb") - m.template "unit_test.rb", File.join('test/unit', - class_path, - "#{file_name}_test.rb") + m.template "mailer.rb", "app/models/#{file_name}.rb" + m.template "unit_test.rb", "test/unit/#{file_name}_test.rb" + + # Views and fixtures directories. + m.directory "app/views/#{file_name}" + m.directory "test/fixtures/#{table_name}" # View template and fixture for each action. actions.each do |action| m.template "view.rhtml", - File.join('app/views', class_path, file_name, "#{action}.rhtml"), + "app/views/#{file_name}/#{action}.rhtml", :assigns => { :action => action } m.template "fixture.rhtml", "test/fixtures/#{table_name}/#{action}", - File.join('test/fixtures', class_path, table_name, action), :assigns => { :action => action } end end diff --git a/railties/lib/rails_generator/generators/components/model/model_generator.rb b/railties/lib/rails_generator/generators/components/model/model_generator.rb index c3407ca283..32577d08a3 100644 --- a/railties/lib/rails_generator/generators/components/model/model_generator.rb +++ b/railties/lib/rails_generator/generators/components/model/model_generator.rb @@ -4,11 +4,6 @@ class ModelGenerator < Rails::Generator::NamedBase # Check for class naming collisions. m.class_collisions class_name, "#{class_name}Test" - # Model, test, and fixture directories. - m.directory File.join('app/models', class_path) - m.directory File.join('test/unit', class_path) - m.directory File.join('test/fixtures', class_path) - # Model class, unit test, and fixtures. m.template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb") m.template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb") diff --git a/railties/lib/rails_generator/generators/components/model/templates/fixtures.yml b/railties/lib/rails_generator/generators/components/model/templates/fixtures.yml index 6285727968..fc3185dc46 100644 --- a/railties/lib/rails_generator/generators/components/model/templates/fixtures.yml +++ b/railties/lib/rails_generator/generators/components/model/templates/fixtures.yml @@ -1,8 +1,10 @@ # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html # Set the $base_id variable in the setup method of your tests. # It's used to ensure that ids don't clash in some databases. +<%% $base_id ||= 100000 %> + first_<%= singular_name %>: - id: 1 + id: <%%= $base_id %> another_<%= singular_name %>: - id: 2 + id: <%%= $base_id + 1 %> diff --git a/railties/lib/rails_generator/generators/components/model/templates/unit_test.rb b/railties/lib/rails_generator/generators/components/model/templates/unit_test.rb index e8714b589a..db0fbf5d33 100644 --- a/railties/lib/rails_generator/generators/components/model/templates/unit_test.rb +++ b/railties/lib/rails_generator/generators/components/model/templates/unit_test.rb @@ -4,11 +4,11 @@ class <%= class_name %>Test < Test::Unit::TestCase fixtures :<%= table_name %> def setup - @<%= singular_name %> = <%= class_name %>.find(1) + $base_id = 1000001 end # Replace this with your real tests. def test_truth - assert_kind_of <%= class_name %>, @<%= singular_name %> + assert true end end diff --git a/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb b/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb index abf9d79ffe..4445995b46 100644 --- a/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb +++ b/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb @@ -41,12 +41,7 @@ class ScaffoldGenerator < Rails::Generator::NamedBase super @controller_name = args.shift || @name.pluralize base_name, @controller_class_path, @controller_class_nesting = extract_modules(@controller_name) - @controller_class_name_without_nesting, @controller_singular_name, @controller_plural_name = inflect_names(base_name) - if @controller_class_nesting.empty? - @controller_class_name = @controller_class_name_without_nesting - else - @controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}" - end + @controller_class_name, @controller_singular_name, @controller_plural_name = inflect_names(base_name) end def manifest @@ -57,12 +52,8 @@ class ScaffoldGenerator < Rails::Generator::NamedBase # Check for class naming collisions. m.class_collisions "#{controller_class_name}Controller", "#{controller_class_name}ControllerTest", "#{controller_class_name}Helper" - # Controller, helper, views, and test directories. - m.directory File.join('app/controllers', controller_class_path) - m.directory File.join('app/helpers', controller_class_path) + # Views directory. m.directory File.join('app/views', controller_class_path, controller_file_name) - m.directory File.join('test/functional', controller_class_path) - # Controller class, functional test, helper, and views. m.template 'controller.rb', @@ -88,8 +79,7 @@ class ScaffoldGenerator < Rails::Generator::NamedBase scaffold_views.each do |action| m.template "view_#{action}.rhtml", File.join('app/views', - controller_class_path, - controller_file_name, + controller_class_path, controller_file_name, "#{action}.rhtml"), :assigns => { :action => action } end @@ -113,8 +103,7 @@ class ScaffoldGenerator < Rails::Generator::NamedBase unscaffolded_actions.each do |action| m.template "controller:view.rhtml", File.join('app/views', - controller_class_path, - controller_file_name, + controller_class_path, controller_file_name, "#{action}.rhtml"), :assigns => { :action => action } end @@ -164,13 +153,9 @@ class ScaffoldGenerator < Rails::Generator::NamedBase end def model_instance - base = class_nesting.split('::').inject(Object) do |base, nested| - break base.const_get(nested) if base.const_defined?(nested) - base.const_set(nested, Module.new) - end - unless base.const_defined?(@class_name_without_nesting) - base.const_set(@class_name_without_nesting, Class.new(ActiveRecord::Base)) + unless Object.const_defined?(class_name) + Object.const_set(class_name, Class.new(ActiveRecord::Base)) end - class_name.constantize.new + Object.const_get(class_name).new end end diff --git a/railties/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb b/railties/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb index 32185fb715..ea9c8e4e94 100644 --- a/railties/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb +++ b/railties/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb @@ -8,9 +8,9 @@ class <%= controller_class_name %>ControllerTest < Test::Unit::TestCase fixtures :<%= table_name %> def setup + $base_id = 1000001 @controller = <%= controller_class_name %>Controller.new - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new + @request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new end <% for action in unscaffolded_actions -%> @@ -34,7 +34,7 @@ class <%= controller_class_name %>ControllerTest < Test::Unit::TestCase end def test_show<%= suffix %> - process :show<%= suffix %>, 'id' => 1 + process :show<%= suffix %>, 'id' => $base_id assert_rendered_file 'show' assert_template_has '<%= singular_name %>' assert_valid_record '<%= singular_name %>' @@ -56,25 +56,25 @@ class <%= controller_class_name %>ControllerTest < Test::Unit::TestCase end def test_edit<%= suffix %> - process :edit<%= suffix %>, 'id' => 1 + process :edit<%= suffix %>, 'id' => $base_id assert_rendered_file 'edit<%= suffix %>' assert_template_has '<%= singular_name %>' assert_valid_record '<%= singular_name %>' end def test_update<%= suffix %> - process :update<%= suffix %>, '<%= singular_name %>' => { 'id' => 1 } - assert_redirected_to :action => 'show<%= suffix %>', :id => 1 + process :update<%= suffix %>, '<%= singular_name %>' => { 'id' => $base_id } + assert_redirected_to :action => 'show<%= suffix %>', :id => $base_id end def test_destroy<%= suffix %> - assert_not_nil <%= class_name %>.find(1) + assert_not_nil <%= class_name %>.find($base_id) - process :destroy, 'id' => 1 + process :destroy, 'id' => $base_id assert_redirected_to :action => 'list<%= suffix %>' assert_raise(ActiveRecord::RecordNotFound) { - <%= singular_name %> = <%= class_name %>.find(1) + <%= singular_name %> = <%= class_name %>.find($base_id) } end end diff --git a/railties/lib/rails_generator/generators/components/scaffold/templates/view_list.rhtml b/railties/lib/rails_generator/generators/components/scaffold/templates/view_list.rhtml index e0d56d1122..068fd67472 100644 --- a/railties/lib/rails_generator/generators/components/scaffold/templates/view_list.rhtml +++ b/railties/lib/rails_generator/generators/components/scaffold/templates/view_list.rhtml @@ -10,7 +10,7 @@ <%% for <%= singular_name %> in @<%= plural_name %> %> <tr> <%% for column in <%= class_name %>.content_columns %> - <td><%%=h <%= singular_name %>.send(column.name) %></td> + <td><%%=h <%= singular_name %>[column.name] %></td> <%% end %> <td><%%= link_to 'Show', :action => 'show<%= suffix %>', :id => <%= singular_name %>.id %></td> <td><%%= link_to 'Edit', :action => 'edit<%= suffix %>', :id => <%= singular_name %>.id %></td> diff --git a/railties/lib/rails_generator/lookup.rb b/railties/lib/rails_generator/lookup.rb index 00b78ce645..ba47fd79be 100644 --- a/railties/lib/rails_generator/lookup.rb +++ b/railties/lib/rails_generator/lookup.rb @@ -4,20 +4,24 @@ class Object class << self # Lookup missing generators using const_missing. This allows any # generator to reference another without having to know its location: - # RubyGems, ~/.rails/generators, and RAILS_ROOT/script/generators. - def lookup_missing_generator(class_id) - if md = /(.+)Generator$/.match(class_id.to_s) - name = md.captures.first.demodulize.underscore - Rails::Generator::Base.lookup(name).klass - else - const_missing_before_generators(class_id) + # RubyGems, ~/.rails/generators, and RAILS_ROOT/script/generators all + # cooperate to get the job done. The greatest use of const_missing + # autoloading is to easily subclass existing generators. Example: + # class HorsebackGenerator < PostbackGenerator + # We don't know whether the postback generator is built in, installed + # as a gem, or in the user's home directory, and we shouldn't have to. + unless respond_to?(:pre_generator_const_missing) + alias_method :pre_generator_const_missing, :const_missing + + def const_missing(class_id) + if md = /(.+)Generator$/.match(class_id.to_s) + name = md.captures.first.demodulize.underscore + Rails::Generator::Base.lookup(name).klass + else + pre_generator_const_missing(class_id) + end end end - - unless respond_to?(:const_missing_before_generators) - alias_method :const_missing_before_generators, :const_missing - alias_method :const_missing, :lookup_missing_generator - end end end @@ -98,7 +102,7 @@ module Rails # 4. Builtins. Model, controller, mailer, scaffold. def use_component_sources! reset_sources - sources << PathSource.new(:app, "#{::RAILS_ROOT}/script/generators") if defined? ::RAILS_ROOT + sources << PathSource.new(:app, "#{Object.const_get(:RAILS_ROOT)}/script/generators") if Object.const_defined?(:RAILS_ROOT) sources << PathSource.new(:user, "#{Dir.user_home}/.rails/generators") sources << GemSource.new if Object.const_defined?(:Gem) sources << PathSource.new(:builtin, "#{File.dirname(__FILE__)}/generators/components") diff --git a/railties/lib/rails_generator/options.rb b/railties/lib/rails_generator/options.rb index 54785413ef..afe2d31625 100644 --- a/railties/lib/rails_generator/options.rb +++ b/railties/lib/rails_generator/options.rb @@ -1,12 +1,8 @@ require 'optparse' -require File.dirname(__FILE__) + '/support/class_inheritable_attributes' +require File.dirname(__FILE__) + '/../support/class_inheritable_attributes' module Rails module Generator - # Implement add_options! to add your options to the parser: - # def add_options!(opt) - # opt.on('-v', '--verbose') { |value| options[:verbose] = value } - # end module Options def self.append_features(base) super @@ -89,14 +85,13 @@ module Rails @option_parser = OptionParser.new do |opt| opt.banner = banner - add_options!(opt) if respond_to?(:add_options!) + add_options!(opt) add_general_options!(opt) opt.parse!(args) end - return args - ensure self.options = full_options(runtime_options) + args end # Raise a usage error. Override usage_message to provide a blurb @@ -114,6 +109,14 @@ module Rails "Usage: #{$0} [options]" end + # Override with a method that adds options to the parser. + # Added options should use the options hash. For example, + # def add_options!(opt) + # opt.on('-v', '--verbose') { |value| options[:verbose] = value } + # end + def add_options!(opt) + end + # Adds general options like -h and --quiet. Usually don't override. def add_general_options!(opt) opt.separator '' diff --git a/railties/lib/rails_generator/scripts.rb b/railties/lib/rails_generator/scripts.rb index f0b6b6f1ff..007980dcb5 100644 --- a/railties/lib/rails_generator/scripts.rb +++ b/railties/lib/rails_generator/scripts.rb @@ -16,23 +16,21 @@ module Rails # or first remaining argument, and invokes the requested command. def run(args = [], runtime_options = {}) begin - parse!(args.dup, runtime_options) - rescue OptionParser::InvalidOption => e - # Don't cry, script. Generators want what you think is invalid. - end + parse!(args, runtime_options) - # Generator name is the only required option. - unless options[:generator] - usage if args.empty? - options[:generator] ||= args.shift - end + # Generator name is the only required option. + unless options[:generator] + usage if args.empty? + options[:generator] ||= args.shift + end - # Look up generator instance and invoke command on it. - Rails::Generator::Base.instance(options[:generator], args, options).command(options[:command]).invoke! - rescue => e - puts e - puts " #{e.backtrace.join("\n ")}\n" if options[:backtrace] - raise SystemExit + # Look up generator instance and invoke command on it. + Rails::Generator::Base.instance(options[:generator], args, options).command(options[:command]).invoke! + rescue => e + puts e + puts " #{e.backtrace.join("\n ")}\n" if options[:backtrace] + raise SystemExit + end end protected diff --git a/railties/lib/rails_generator/scripts/destroy.rb b/railties/lib/rails_generator/scripts/destroy.rb index 628ec4de32..fd8469fbc7 100644 --- a/railties/lib/rails_generator/scripts/destroy.rb +++ b/railties/lib/rails_generator/scripts/destroy.rb @@ -3,5 +3,9 @@ require File.dirname(__FILE__) + '/../scripts' module Rails::Generator::Scripts class Destroy < Base mandatory_options :command => :destroy + + protected + def add_options!(opt) + end end end diff --git a/railties/lib/rails_generator/scripts/generate.rb b/railties/lib/rails_generator/scripts/generate.rb index 1fe2f54ab3..329d6691df 100644 --- a/railties/lib/rails_generator/scripts/generate.rb +++ b/railties/lib/rails_generator/scripts/generate.rb @@ -3,5 +3,9 @@ require File.dirname(__FILE__) + '/../scripts' module Rails::Generator::Scripts class Generate < Base mandatory_options :command => :create + + protected + def add_options!(opt) + end end end diff --git a/railties/lib/rails_generator/scripts/update.rb b/railties/lib/rails_generator/scripts/update.rb index 53a9faa366..ad1ae8004a 100644 --- a/railties/lib/rails_generator/scripts/update.rb +++ b/railties/lib/rails_generator/scripts/update.rb @@ -5,6 +5,9 @@ module Rails::Generator::Scripts mandatory_options :command => :update protected + def add_options!(opt) + end + def banner "Usage: #{$0} [options] scaffold" end diff --git a/railties/test/rails_generator_test.rb b/railties/test/rails_generator_test.rb index 5934bb3e7b..8470bed943 100644 --- a/railties/test/rails_generator_test.rb +++ b/railties/test/rails_generator_test.rb @@ -1,29 +1,22 @@ +$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib" +RAILS_ROOT = File.dirname(__FILE__) + require 'test/unit' -# Optionally load RubyGems. +require 'rails_generator' +require 'rails_generator/simple_logger' +Rails::Generator::Base.logger = Rails::Generator::SimpleLogger.new + begin require 'rubygems' + require_gem 'actionpack' rescue LoadError end -# Must set before requiring generator libs. -RAILS_ROOT = File.dirname(__FILE__) - -# Preemptively load the rest of Rails so Gems don't hijack our requires. -require File.dirname(__FILE__) + '/../../activerecord/lib/active_record' -require File.dirname(__FILE__) + '/../../actionpack/lib/action_controller' -require File.dirname(__FILE__) + '/../lib/rails_generator' - class RailsGeneratorTest < Test::Unit::TestCase BUILTINS = %w(controller mailer model scaffold) CAPITALIZED_BUILTINS = BUILTINS.map { |b| b.capitalize } - def test_sources - expected = [:app, :user, :RubyGems, :builtin] - expected.delete(:gem) unless Object.const_defined?(:Gem) - assert_equal expected, Rails::Generator::Base.sources.map { |s| s.label } - end - def test_lookup_builtins (BUILTINS + CAPITALIZED_BUILTINS).each do |name| assert_nothing_raised do @@ -78,7 +71,7 @@ class RailsGeneratorTest < Test::Unit::TestCase assert_equal 'admin/foo', g.name assert_equal %w(admin), g.class_path assert_equal 'Admin', g.class_nesting - assert_equal 'Admin::Foo', g.class_name + assert_equal 'Foo', g.class_name assert_equal 'foo', g.singular_name assert_equal 'foos', g.plural_name assert_equal g.singular_name, g.file_name |