diff options
author | rick <rick@spacemonkey.local> | 2008-04-23 12:14:59 -0700 |
---|---|---|
committer | rick <rick@spacemonkey.local> | 2008-04-23 12:14:59 -0700 |
commit | eacb5cf0cab6447db78085c8bda6c94dd329ce6b (patch) | |
tree | df4bc7789c4d1fe83085b725be0d1fe4a6223880 /actionpack/lib | |
parent | 69d29e80f76079262f2e98e350592be1cfdfcd1e (diff) | |
parent | 6c1c16bfd9eb865dffa68c12c7df66d5a59a8714 (diff) | |
download | rails-eacb5cf0cab6447db78085c8bda6c94dd329ce6b.tar.gz rails-eacb5cf0cab6447db78085c8bda6c94dd329ce6b.tar.bz2 rails-eacb5cf0cab6447db78085c8bda6c94dd329ce6b.zip |
Merge branch 'master' of git@github.com:rails/rails
Diffstat (limited to 'actionpack/lib')
-rwxr-xr-x | actionpack/lib/action_controller/base.rb | 56 | ||||
-rw-r--r-- | actionpack/lib/action_controller/caching/actions.rb | 5 | ||||
-rw-r--r-- | actionpack/lib/action_controller/caching/pages.rb | 12 | ||||
-rw-r--r-- | actionpack/lib/action_controller/dispatcher.rb | 75 | ||||
-rw-r--r-- | actionpack/lib/action_controller/filters.rb | 6 | ||||
-rw-r--r-- | actionpack/lib/action_controller/layout.rb | 4 | ||||
-rw-r--r-- | actionpack/lib/action_controller/rescue.rb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_controller/resources.rb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_view.rb | 7 | ||||
-rw-r--r-- | actionpack/lib/action_view/base.rb | 24 | ||||
-rwxr-xr-x | actionpack/lib/action_view/helpers/date_helper.rb | 6 | ||||
-rw-r--r-- | actionpack/lib/action_view/inline_template.rb | 20 | ||||
-rw-r--r-- | actionpack/lib/action_view/template.rb | 38 | ||||
-rw-r--r-- | actionpack/lib/action_view/test_case.rb | 64 |
14 files changed, 183 insertions, 138 deletions
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 63ad4d042a..0c0d0ec4ac 100755 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -16,9 +16,6 @@ module ActionController #:nodoc: class SessionRestoreError < ActionControllerError #:nodoc: end - class MissingTemplate < ActionControllerError #:nodoc: - end - class RenderError < ActionControllerError #:nodoc: end @@ -256,16 +253,12 @@ module ActionController #:nodoc: DEFAULT_RENDER_STATUS_CODE = "200 OK" include StatusCodes - - # Determines whether the view has access to controller internals @request, @response, @session, and @template. - # By default, it does. - @@view_controller_internals = true - cattr_accessor :view_controller_internals - - # Protected instance variable cache - @@protected_variables_cache = nil - cattr_accessor :protected_variables_cache - + + # Controller specific instance variables which will not be accessible inside views. + @@protected_view_variables = %w(@assigns @performed_redirect @performed_render @variables_added @request_origin @url @parent_controller + @action_name @before_filter_chain_aborted @action_cache_path @_session @_cookies @_headers @_params + @_flash @_response) + # Prepends all the URL-generating helpers from AssetHelper. This makes it possible to easily move javascripts, stylesheets, # and images to a dedicated asset server away from the main web server. Example: # ActionController::Base.asset_host = "http://assets.example.com" @@ -330,9 +323,6 @@ module ActionController #:nodoc: # Can be set to nil for no logging. Compatible with both Ruby's own Logger and Log4r loggers. cattr_accessor :logger - # Turn on +ignore_missing_templates+ if you want to unit test actions without making the associated templates. - cattr_accessor :ignore_missing_templates - # Controls the resource action separator @@resource_action_separator = "/" cattr_accessor :resource_action_separator @@ -870,7 +860,7 @@ module ActionController #:nodoc: elsif inline = options[:inline] add_variables_to_assigns - tmpl = ActionView::Template.new(@template, options[:inline], false, options[:locals], true, options[:type]) + tmpl = ActionView::InlineTemplate.new(@template, options[:inline], options[:locals], options[:type]) render_for_text(@template.render_template(tmpl), options[:status]) elsif action_name = options[:action] @@ -1105,7 +1095,6 @@ module ActionController #:nodoc: private def render_for_file(template_path, status = nil, use_full_path = false, locals = {}) #:nodoc: add_variables_to_assigns - assert_existence_of_template_file(template_path) if use_full_path logger.info("Rendering #{template_path}" + (status ? " (#{status})" : '')) if logger render_for_text(@template.render_file(template_path, use_full_path, locals), status) end @@ -1201,7 +1190,6 @@ module ActionController #:nodoc: def add_variables_to_assigns unless @variables_added add_instance_variables_to_assigns - add_class_variables_to_assigns if view_controller_internals @variables_added = true end end @@ -1215,30 +1203,11 @@ module ActionController #:nodoc: end def add_instance_variables_to_assigns - @@protected_variables_cache ||= Set.new(protected_instance_variables) - instance_variable_names.each do |var| - next if @@protected_variables_cache.include?(var) + (instance_variable_names - @@protected_view_variables).each do |var| @assigns[var[1..-1]] = instance_variable_get(var) end end - def add_class_variables_to_assigns - %w(view_paths logger ignore_missing_templates).each do |cvar| - @assigns[cvar] = self.send(cvar) - end - end - - def protected_instance_variables - if view_controller_internals - %w(@assigns @performed_redirect @performed_render) - else - %w(@assigns @performed_redirect @performed_render - @_request @request @_response @response @_params @params - @_session @session @_cookies @cookies - @template @request_origin @parent_controller) - end - end - def request_origin # this *needs* to be cached! # otherwise you'd get different results if calling it more than once @@ -1267,15 +1236,6 @@ module ActionController #:nodoc: @@exempt_from_layout.any? { |ext| name_with_extension =~ ext } end - def assert_existence_of_template_file(template_name) - unless template_exists?(template_name) || ignore_missing_templates - full_template_path = template_name.include?('.') ? template_name : "#{template_name}.#{@template.template_format}.erb" - display_paths = view_paths.join(':') - template_type = (template_name =~ /layouts/i) ? 'layout' : 'template' - raise(MissingTemplate, "Missing #{template_type} #{full_template_path} in view path #{display_paths}") - end - end - def default_template_name(action_name = self.action_name) if action_name action_name = action_name.to_s diff --git a/actionpack/lib/action_controller/caching/actions.rb b/actionpack/lib/action_controller/caching/actions.rb index 4410e47eb3..7b0551c664 100644 --- a/actionpack/lib/action_controller/caching/actions.rb +++ b/actionpack/lib/action_controller/caching/actions.rb @@ -41,7 +41,6 @@ module ActionController #:nodoc: base.extend(ClassMethods) base.class_eval do attr_accessor :rendered_action_cache, :action_cache_path - alias_method_chain :protected_instance_variables, :action_caching end end @@ -55,10 +54,6 @@ module ActionController #:nodoc: end protected - def protected_instance_variables_with_action_caching - protected_instance_variables_without_action_caching + %w(@action_cache_path) - end - def expire_action(options = {}) return unless cache_configured? diff --git a/actionpack/lib/action_controller/caching/pages.rb b/actionpack/lib/action_controller/caching/pages.rb index 755f1e4e0a..7aa6ce154b 100644 --- a/actionpack/lib/action_controller/caching/pages.rb +++ b/actionpack/lib/action_controller/caching/pages.rb @@ -78,10 +78,18 @@ module ActionController #:nodoc: # Caches the +actions+ using the page-caching approach that'll store the cache in a path within the page_cache_directory that # matches the triggering url. + # + # Usage: + # + # # cache the index action + # caches_page :index + # + # # cache the index action except for JSON requests + # caches_page :index, :if => Proc.new { |c| !c.request.format.json? } def caches_page(*actions) return unless perform_caching - actions = actions.map(&:to_s) - after_filter { |c| c.cache_page if actions.include?(c.action_name) } + options = actions.extract_options! + after_filter({:only => actions}.merge(options)) { |c| c.cache_page } end private diff --git a/actionpack/lib/action_controller/dispatcher.rb b/actionpack/lib/action_controller/dispatcher.rb index 30db7d9f73..6e1e7a261f 100644 --- a/actionpack/lib/action_controller/dispatcher.rb +++ b/actionpack/lib/action_controller/dispatcher.rb @@ -5,6 +5,30 @@ module ActionController @@guard = Mutex.new class << self + def define_dispatcher_callbacks(cache_classes) + unless cache_classes + # Development mode callbacks + before_dispatch :reload_application + after_dispatch :cleanup_application + end + + # Common callbacks + to_prepare :load_application_controller do + begin + require_dependency 'application' unless defined?(::ApplicationController) + rescue LoadError => error + raise unless error.message =~ /application\.rb/ + end + end + + if defined?(ActiveRecord) + before_dispatch { ActiveRecord::Base.verify_active_connections! } + to_prepare(:activerecord_instantiate_observers) { ActiveRecord::Base.instantiate_observers } + end + + after_dispatch :flush_logger if defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER.respond_to?(:flush) + end + # Backward-compatible class method takes CGI-specific args. Deprecated # in favor of Dispatcher.new(output, request, response).dispatch. def dispatch(cgi = nil, session_options = CgiRequest::DEFAULT_SESSION_OPTIONS, output = $stdout) @@ -22,7 +46,7 @@ module ActionController def to_prepare(identifier = nil, &block) @prepare_dispatch_callbacks ||= ActiveSupport::Callbacks::CallbackChain.new callback = ActiveSupport::Callbacks::Callback.new(:prepare_dispatch, block, :identifier => identifier) - @prepare_dispatch_callbacks.replace_or_append_callback(callback) + @prepare_dispatch_callbacks | callback end # If the block raises, send status code as a last-ditch response. @@ -69,23 +93,9 @@ module ActionController cattr_accessor :error_file_path self.error_file_path = Rails.public_path if defined?(Rails.public_path) - cattr_accessor :unprepared - self.unprepared = true - include ActiveSupport::Callbacks define_callbacks :prepare_dispatch, :before_dispatch, :after_dispatch - before_dispatch :reload_application - before_dispatch :prepare_application - after_dispatch :flush_logger - after_dispatch :cleanup_application - - if defined? ActiveRecord - to_prepare :activerecord_instantiate_observers do - ActiveRecord::Base.instantiate_observers - end - end - def initialize(output, request = nil, response = nil) @output, @request, @response = output, request, response end @@ -114,40 +124,23 @@ module ActionController end def reload_application - if Dependencies.load? - Routing::Routes.reload - self.unprepared = true - end - end + # Run prepare callbacks before every request in development mode + run_callbacks :prepare_dispatch - def prepare_application(force = false) - begin - require_dependency 'application' unless defined?(::ApplicationController) - rescue LoadError => error - raise unless error.message =~ /application\.rb/ - end - - ActiveRecord::Base.verify_active_connections! if defined?(ActiveRecord) - - if unprepared || force - run_callbacks :prepare_dispatch - ActionView::TemplateFinder.reload! unless ActionView::Base.cache_template_loading - self.unprepared = false - end + Routing::Routes.reload + ActionView::TemplateFinder.reload! unless ActionView::Base.cache_template_loading end # Cleanup the application by clearing out loaded classes so they can # be reloaded on the next request without restarting the server. - def cleanup_application(force = false) - if Dependencies.load? || force - ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord) - Dependencies.clear - ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord) - end + def cleanup_application + ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord) + Dependencies.clear + ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord) end def flush_logger - RAILS_DEFAULT_LOGGER.flush if defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER.respond_to?(:flush) + RAILS_DEFAULT_LOGGER.flush end protected diff --git a/actionpack/lib/action_controller/filters.rb b/actionpack/lib/action_controller/filters.rb index 73721cd1ec..8c97787741 100644 --- a/actionpack/lib/action_controller/filters.rb +++ b/actionpack/lib/action_controller/filters.rb @@ -265,7 +265,7 @@ module ActionController #:nodoc: def skip_filter_in_chain(*filters, &test) filters, conditions = extract_options(filters) filters.each do |filter| - if callback = find_callback(filter) then delete(callback) end + if callback = find(filter) then delete(callback) end end if conditions.empty? update_filter_in_chain(filters, :skip => conditions, &test) end @@ -302,7 +302,7 @@ module ActionController #:nodoc: def find_or_create_filter(filter, filter_type, options = {}) update_filter_in_chain([filter], options) - if found_filter = find_callback(filter) { |f| f.type == filter_type } + if found_filter = find(filter) { |f| f.type == filter_type } found_filter else filter_kind = case @@ -326,7 +326,7 @@ module ActionController #:nodoc: end def update_filter_in_chain(filters, options, &test) - filters.map! { |f| block_given? ? find_callback(f, &test) : find_callback(f) } + filters.map! { |f| block_given? ? find(f, &test) : find(f) } filters.compact! map! do |filter| diff --git a/actionpack/lib/action_controller/layout.rb b/actionpack/lib/action_controller/layout.rb index 5484add3b5..b5b59f2d7c 100644 --- a/actionpack/lib/action_controller/layout.rb +++ b/actionpack/lib/action_controller/layout.rb @@ -244,9 +244,7 @@ module ActionController #:nodoc: def render_with_a_layout(options = nil, extra_options = {}, &block) #:nodoc: template_with_options = options.is_a?(Hash) - if apply_layout?(template_with_options, options) && (layout = pick_layout(template_with_options, options)) - assert_existence_of_template_file(layout) - + if (layout = pick_layout(template_with_options, options)) && apply_layout?(template_with_options, options) options = options.merge :layout => false if template_with_options logger.info("Rendering template within #{layout}") if logger diff --git a/actionpack/lib/action_controller/rescue.rb b/actionpack/lib/action_controller/rescue.rb index f5ad04532b..d4d561bdb7 100644 --- a/actionpack/lib/action_controller/rescue.rb +++ b/actionpack/lib/action_controller/rescue.rb @@ -26,7 +26,7 @@ module ActionController #:nodoc: DEFAULT_RESCUE_TEMPLATE = 'diagnostics' DEFAULT_RESCUE_TEMPLATES = { - 'ActionController::MissingTemplate' => 'missing_template', + 'ActionView::MissingTemplate' => 'missing_template', 'ActionController::RoutingError' => 'routing_error', 'ActionController::UnknownAction' => 'unknown_action', 'ActionView::TemplateError' => 'template_error' diff --git a/actionpack/lib/action_controller/resources.rb b/actionpack/lib/action_controller/resources.rb index df7d6ead1b..d3cedfdac7 100644 --- a/actionpack/lib/action_controller/resources.rb +++ b/actionpack/lib/action_controller/resources.rb @@ -527,7 +527,7 @@ module ActionController action_path = action if resource.options[:path_names] action_path = resource.options[:path_names][action] - action_path ||= Base.resources_path_names[action] + action_path ||= Base.resources_path_names[action] || action end map.named_route("#{action}_#{resource.name_prefix}#{resource.singular}", "#{resource.member_path}#{resource.action_separator}#{action_path}", action_options) diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb index e20812d308..609334d52d 100644 --- a/actionpack/lib/action_view.rb +++ b/actionpack/lib/action_view.rb @@ -30,6 +30,7 @@ require 'action_view/template_handlers/rjs' require 'action_view/template_finder' require 'action_view/template' require 'action_view/partial_template' +require 'action_view/inline_template' require 'action_view/base' require 'action_view/partials' @@ -37,6 +38,8 @@ require 'action_view/template_error' ActionView::Base.class_eval do include ActionView::Partials -end -ActionView::Base.load_helpers + ActionView::Base.helper_modules.each do |helper_module| + include helper_module + end +end diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index e83c8b6bd3..4ed20fec89 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -1,6 +1,9 @@ module ActionView #:nodoc: class ActionViewError < StandardError #:nodoc: end + + class MissingTemplate < ActionViewError #:nodoc: + end # Action View templates can be written in three ways. If the template file has a +.erb+ (or +.rhtml+) extension then it uses a mixture of ERb # (included in Ruby) and HTML. If the template file has a +.builder+ (or +.rxml+) extension then Jim Weirich's Builder::XmlMarkup library is used. @@ -153,9 +156,6 @@ module ActionView #:nodoc: attr_reader :finder attr_accessor :base_path, :assigns, :template_extension, :first_render attr_accessor :controller - - attr_reader :logger, :response, :headers - attr_internal :cookies, :flash, :headers, :params, :request, :response, :session attr_writer :template_format attr_accessor :current_render_extension @@ -182,7 +182,10 @@ module ActionView #:nodoc: @@erb_variable = '_erbout' cattr_accessor :erb_variable - delegate :request_forgery_protection_token, :to => :controller + attr_internal :request + + delegate :request_forgery_protection_token, :template, :params, :session, :cookies, :response, :headers, + :flash, :logger, :to => :controller module CompiledTemplates #:nodoc: # holds compiled template code @@ -202,22 +205,23 @@ module ActionView #:nodoc: class ObjectWrapper < Struct.new(:value) #:nodoc: end - def self.load_helpers #:nodoc: - Dir.entries("#{File.dirname(__FILE__)}/helpers").sort.each do |file| + def self.helper_modules #:nodoc: + helpers = [] + Dir.entries(File.expand_path("#{File.dirname(__FILE__)}/helpers")).sort.each do |file| next unless file =~ /^([a-z][a-z_]*_helper).rb$/ require "action_view/helpers/#{$1}" helper_module_name = $1.camelize if Helpers.const_defined?(helper_module_name) - include Helpers.const_get(helper_module_name) + helpers << Helpers.const_get(helper_module_name) end end + return helpers end def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil)#:nodoc: @assigns = assigns_for_first_render @assigns_added = nil @controller = controller - @logger = controller && controller.logger @finder = TemplateFinder.new(self, view_paths) end @@ -279,7 +283,7 @@ If you are rendering a subtemplate, you must now use controller-like partial syn elsif options[:partial] render_partial(options[:partial], ActionView::Base::ObjectWrapper.new(options[:object]), options[:locals]) elsif options[:inline] - template = Template.new(self, options[:inline], false, options[:locals], true, options[:type]) + template = InlineTemplate.new(self, options[:inline], options[:locals], options[:type]) render_template(template) end end @@ -320,7 +324,7 @@ If you are rendering a subtemplate, you must now use controller-like partial syn end end - private + private def wrap_content_for_layout(content) original_content_for_layout = @content_for_layout @content_for_layout = content diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index c71d59f373..9f7790d0f9 100755 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -250,7 +250,7 @@ module ActionView # # prefixed with 'payday' rather than 'date' # select_datetime(my_date_time, :prefix => 'payday') # - def select_datetime(datetime = Time.now, options = {}, html_options = {}) + def select_datetime(datetime = Time.current, options = {}, html_options = {}) separator = options[:datetime_separator] || '' select_date(datetime, options, html_options) + separator + select_time(datetime, options, html_options) end @@ -321,7 +321,7 @@ module ActionView # # separated by ':' and includes an input for seconds # select_time(my_time, :time_separator => ':', :include_seconds => true) # - def select_time(datetime = Time.now, options = {}, html_options = {}) + def select_time(datetime = Time.current, options = {}, html_options = {}) separator = options[:time_separator] || '' select_hour(datetime, options, html_options) + separator + select_minute(datetime, options, html_options) + (options[:include_seconds] ? separator + select_second(datetime, options, html_options) : '') end @@ -675,7 +675,7 @@ module ActionView def default_time_from_options(default) case default when nil - Time.now + Time.current when Date, Time default else diff --git a/actionpack/lib/action_view/inline_template.rb b/actionpack/lib/action_view/inline_template.rb new file mode 100644 index 0000000000..87c012d181 --- /dev/null +++ b/actionpack/lib/action_view/inline_template.rb @@ -0,0 +1,20 @@ +module ActionView #:nodoc: + class InlineTemplate < Template #:nodoc: + + def initialize(view, source, locals = {}, type = nil) + @view = view + @finder = @view.finder + + @source = source + @extension = type + @locals = locals || {} + + @handler = self.class.handler_class_for_extension(@extension).new(@view) + end + + def method_key + @source + end + + end +end diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index 0cd6784fd8..bc3d8d5e52 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -2,22 +2,18 @@ module ActionView #:nodoc: class Template #:nodoc: attr_accessor :locals - attr_reader :handler, :path, :source, :extension, :filename, :path_without_extension, :method + attr_reader :handler, :path, :extension, :filename, :path_without_extension, :method - def initialize(view, path_or_source, use_full_path, locals = {}, inline = false, inline_type = nil) + def initialize(view, path, use_full_path, locals = {}) @view = view @finder = @view.finder - unless inline - # Clear the forward slash at the beginning if exists - @path = use_full_path ? path_or_source.sub(/^\//, '') : path_or_source - @view.first_render ||= @path - @source = nil # Don't read the source until we know that it is required - set_extension_and_file_name(use_full_path) - else - @source = path_or_source - @extension = inline_type - end + # Clear the forward slash at the beginning if exists + @path = use_full_path ? path.sub(/^\//, '') : path + @view.first_render ||= @path + @source = nil # Don't read the source until we know that it is required + set_extension_and_file_name(use_full_path) + @locals = locals || {} @handler = self.class.handler_class_for_extension(@extension).new(@view) end @@ -32,7 +28,7 @@ module ActionView #:nodoc: end def method_key - @method_key ||= (@filename || @source) + @filename end def base_path_for_exception @@ -58,9 +54,8 @@ module ActionView #:nodoc: @filename = @finder.pick_template(@path_without_extension, @extension) else @extension = @finder.pick_template_extension(@path).to_s - unless @extension - raise ActionViewError, "No template found for #{@path} in #{@finder.view_paths.inspect}" - end + raise_missing_template_exception unless @extension + @filename = @finder.pick_template(@path, @extension) @extension = @extension.gsub(/^.+\./, '') # strip off any formats end @@ -68,9 +63,14 @@ module ActionView #:nodoc: @filename = @path end - if @filename.blank? - raise ActionViewError, "Couldn't find template file for #{@path} in #{@finder.view_paths.inspect}" - end + raise_missing_template_exception if @filename.blank? + end + + def raise_missing_template_exception + full_template_path = @path.include?('.') ? @path : "#{@path}.#{@view.template_format}.erb" + display_paths = @finder.view_paths.join(':') + template_type = (@path =~ /layouts/i) ? 'layout' : 'template' + raise(MissingTemplate, "Missing #{template_type} #{full_template_path} in view path #{display_paths}") end # Template Handlers diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb new file mode 100644 index 0000000000..b2e6589d81 --- /dev/null +++ b/actionpack/lib/action_view/test_case.rb @@ -0,0 +1,64 @@ +require 'active_support/test_case' + +module ActionView + class NonInferrableHelperError < ActionViewError + def initialize(name) + super "Unable to determine the helper to test from #{name}. " + + "You'll need to specify it using tests YourHelper in your " + + "test case definition" + end + end + + class TestCase < ActiveSupport::TestCase + class_inheritable_accessor :helper_class + @@helper_class = nil + + class << self + def tests(helper_class) + self.helper_class = helper_class + end + + def helper_class + if current_helper_class = read_inheritable_attribute(:helper_class) + current_helper_class + else + self.helper_class = determine_default_helper_class(name) + end + end + + def determine_default_helper_class(name) + name.sub(/Test$/, '').constantize + rescue NameError + raise NonInferrableHelperError.new(name) + end + end + + ActionView::Base.helper_modules.each do |helper_module| + include helper_module + end + include ActionController::PolymorphicRoutes + include ActionController::RecordIdentifier + + setup :setup_with_helper_class + + def setup_with_helper_class + self.class.send(:include, helper_class) + end + + class TestController < ActionController::Base + attr_accessor :request, :response + + def initialize + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + end + end + + private + def method_missing(selector, *args) + controller = TestController.new + return controller.send!(selector, *args) if ActionController::Routing::Routes.named_routes.helpers.include?(selector) + super + end + end +end |